C # Verwendung von Generika und Schnittstellenimplementierung

8

Kontext: .NET 4.0, C #

Ich erstelle eine Reihe von Schnittstellen und eine Reihe von Klassen, die sie implementieren, um einige Dienste bereitzustellen. Die Clients verwenden die konkreten Klassen, rufen aber Methoden auf, die über die Schnittstellen als Parametertypen deklariert werden.

Ein vereinfachtes Beispiel ist dieses:

%Vor%

Der Code macht für mich Sinn, aber ich bekomme den Compilerfehler:

  

Argument 1:   kann nicht von ' TestGenerics.Form<TestGenerics.Field> ' in konvertiert werden   ' TestGenerics.IForm<TestGenerics.IField> ' TestGenerics

Ich bin nicht sicher, was ich falsch mache, ich habe viele Seiten im Internet gelesen, aber keines hat mein Problem gelöst.

Gibt es eine Lösung, die die Architektur dessen, was ich zu bauen versuche, nicht so sehr verändern würde:

Edit: Ich habe die Interfaces so gestaltet, dass sie unabhängig von konkreten Konstellationen sind, die sie implementieren. Die konkreten Klassen können aus einer DLL geladen werden, aber die meisten der Anwendung arbeitet mit den Schnittstellen. In einigen Fällen muss ich konkrete Klassen verwenden, besonders wenn ich Klassen verwende, die serialisiert werden müssen.

Vielen Dank im Voraus.

Alejandro

    
Sugar 30.07.2013, 15:20
quelle

3 Antworten

13

Das Problem ist, dass Form<Field> implementiert IForm<Field> , aber nicht IForm<IField> . Sie können eine geerbte Klasse (oder Schnittstelle) nicht als generischen Parameter verwenden, es sei denn, sie ist als Kovariante mit dem Bezeichner out gekennzeichnet. Wenn Sie jedoch Ihre Schnittstelle als Kovariante markieren, wird die Verwendung erheblich eingeschränkt (was im Grunde genommen zu einer "Nur-Ausgabe" -Schnittstelle wie IEnumerable führt), so dass sie für Sie möglicherweise nicht funktioniert.

Eine Möglichkeit, es zum Laufen zu bringen, ist, auch TestMethod generisch zu machen:

%Vor%     
D Stanley 30.07.2013, 15:24
quelle
10

Sie können Covariance wie folgt verwenden:

%Vor%

Mehr über Kovarianz und Kontravarianz hier .

    
Tamim Al Manaseer 30.07.2013 15:29
quelle
7

Andere haben auf die Gründe für die Fehlermeldung hingewiesen, aber untersuchen wir kurz das Design Ihres Beispielcodes. Vielleicht verwenden Sie ein generisches, wo keiner benötigt wird.

Sie haben bereits gesagt, dass Sie Methoden verwenden, die in der IField-Schnittstelle deklariert sind. Daher ist es nicht notwendig, Ihre IForm-Klasse generisch zu machen - sie müssen einfach Referenzen auf IField speichern, anstatt auf das generische Argument 'T' ist sowieso garantiert ein IField).

Verwenden Sie zum Beispiel:

%Vor%

statt

%Vor%     
BTownTKD 30.07.2013 16:20
quelle

Tags und Links