VB.NET Implementieren Sie mehrere kontravariante Schnittstellentypen

8

Grundlegende Frage: Gegeben eine Schnittstelle: ICopiesFrom (Of In TModel), wo es keine Typbeschränkung für das generische Argument gibt, kann diese Schnittstelle mehr als einmal für denselben konkreten Typ mit einem anderen implementiert werden Typ Argument ohne eine Compiler-Warnung?

Hintergrundinformationen: Mein Griff zur Kovarianz und Kontravarianz hat in den letzten Jahren dank Eric Lippert, Google, und vielen Stunden des Experimentierens zugenommen. In einem Projekt, an dem ich gerade arbeite, muss ich verschiedene Ebenen der Architektur trennen und keine Basismodell- / Entitätstypen einer höheren Ebene (Präsentation) zugänglich machen. Um dies zu erreichen, habe ich zusammengesetzte Klassen (MVC-Modelle) erstellt, die Aspekte von möglicherweise mehreren unterschiedlichen Grundschichtmodelltypen enthalten. Ich habe einen separaten Layer, der diese zusammengesetzten Typen aus den Basistypen (Service-Layer) erstellt. Eine wichtige Voraussetzung ist, dass die Basistypen nicht über eine Referenz weitergegeben werden. Daher müssen Eigenschaften dupliziert werden, um eine Deep-Copy der Basismodellklasse zu erstellen.

Um den langwierigen und unschönen Code aus der Serviceebene zu entfernen, habe ich eine Schnittstelle erstellt, die einen allgemeinen Vertrag für zusammengesetzte Typen definiert, mit dem die Eigenschaftswerte in das zusammengesetzte Objekt kopiert werden können. Wenn ich diese Schnittstelle jedoch mehrfach implementieren möchte, generiert der VB-Compiler eine Warnung. Das Programm läuft gut, aber ich möchte die Besonderheiten verstehen, warum das passiert. Vor allem, wenn dies eine fragile oder schlechte Designentscheidung ist, möchte ich es jetzt wissen, bevor ich zu tief gehe.

Umgebungsdetails:

  • Sprache: VB.Net
  • .NET: 4.0
  • IDE: VS2010 SP1
  • Verwendung: Website (MVC2)

Bei dem Versuch, das herauszufinden, habe ich etwas über SO und das Internet recherchiert, aber nichts geht wirklich spezifisch auf meine Frage ein. Hier sind einige (aber nicht alle) Ressourcen, die ich konsultiert habe:

Zusammenfassung: Gibt es einen besseren / saubereren / flexibleren Weg, um das zu erreichen, was ich versuche oder tun muss? Ich muss mit der Compiler-Warnung leben?

Hier ist ein lauffähiges Beispiel (nicht der eigentliche Code), das das Problem veranschaulicht:

%Vor%     
xDaevax 28.05.2014, 13:37
quelle

1 Antwort

3
  

Das Programm läuft gut, aber ich möchte die Besonderheiten verstehen   warum dies geschieht

Die Warnung ist wegen der (generischen) Kontravarianz in Bezug auf Interfaces und / oder Klassen mit einer bereits bestehenden Vererbungshierarchie vorhanden. Es gilt nicht speziell für den Fall, den Sie in Ihrem Beispiel angegeben haben (möglicherweise in Ihrem echten Code), aber hier ist der Grund, warum es eine Warnung ist:

nehme an, dass MaterialB das Material A geerbt hat und dann von SpecialB geerbt wurde, dann

%Vor%

kombiniert mit

%Vor%

sagt (aufgrund des 'In'): Composite kann ein ICopiesFrom(Of <anything Inheriting from MaterialA>) sein (mit einer Implementierung) UND Composite kann ein ICopiesFrom(Of <anything Inheriting from MaterialB>) (mit zweiter Implementierung) sein

Also wenn ich sage:

%Vor%

Welche Implementierung sollte sie wählen, beide sind gültig (es scheint natürlich, B zu wählen, aber es ist mehrdeutig)

die Situation wenn vielleicht deutlicher mit Interfaces:

%Vor%

Welche Implementierung sollte der Compiler jetzt verwenden?

Es gibt auch nichts in deinem Beispiel, das das -Schlüsselwort benötigt (vielleicht gibt es das im echten Code). Wenn Sie zum Beispiel Composite AS ICopiesFrom(Of SpecialB) nicht weitergeben müssen, erhalten Sie nichts, die ICopiesFrom(Of MaterialB) können mit SpecialB ohne (Generic) contravariance über die normalen (nicht generischen) Mechanismen umgehen.

    
tolanj 30.07.2014, 14:09
quelle