2010-04-22 23 views
6

Ein komisches Problem bei der Kompimation, das besagt, dass eine Klasse keine Schnittstelle implementiert.Generische Klassenimplementierungsschnittstelle schlägt fehl

Können sagen, ein v eine Klasse bekam:

public Class MyClass 
{ 
... 
} 

und ein interace:

public Interface IMyInterface 
{ 
MyClass PropertyOfMyClass {get;} 
} 

und nun eine generische Klasse:

public class MyGeneric<T> where T:MyClass 
{ 
    T PropertyOfMyClass 
    { 
    get{return ...;} 
    } 
} 

Bis hier every Fein- und kompiliert rechts.

Aber dies wird bei der Kompilierung brechen:

public class MyGeneric<T>:IMyInterace where T:MyClass 
    { 
     T PropertyOfMyClass 
     { 
     get{return ...;} 
     } 
    } 

Zu sagen, dass MyGeneric nicht implementiert Methode von IMyInterface. Aber offensichtlich tut es das nicht?

+0

Der Gedanke, den ich nicht verstehe, ist, dass, wenn T ein Typ oder ein Abkömmling von MyClass ist, die Eigenschaft T PropertyOfMyClass gleich MyClass PropertyOfMyClass ist. Warum kompiliert das nicht? – Pitming

Antwort

6

Sie können keine Eigenschaften (oder Methoden) von Schnittstellen mit Varianz implementieren. Dies betrifft nicht nur Generika. Zum Beispiel:

public interface IFoo 
{ 
    object Bar(); 
} 

public class Foo : IFoo 
{ 
    // This won't compile 
    string Bar() { return "hello"; } 
} 

Jetzt Sie kann runden diese erhalten mit expliziter Schnittstellenimplementierung:

public class Foo : IFoo 
{ 
    // Make the interface implementation call the more strongly-typed method 
    object IFoo.Bar() { return Bar(); } 

    string Bar() { return "hello"; } 
} 

, die für Sie eine Antwort sein kann - oder auch nicht. Wir müssten genau wissen, warum Sie die Eigenschaft als Typ T deklarieren wollten und nicht nur MyClass, um sicher zu sein.

+0

Ich möchte keine MyClass-Instanz zurückgeben, da ich unter Meine Klasse eine vollständige Hierarchie habe und das generische System mir die richtige Klasse ohne Casting zurückgibt. – Pitming

1

Eine andere Lösung wäre, um die Schnittstelle generic selbst zu machen:

public interface IMyInterface<T> where T : MyClass 
{ 
    T PropertyOfMyClass { get; } 
} 

Sie können es dann auf eine Klasse verwenden:

public class MyGenericClass<T> : IMyInterface<T> where T : MyClass 
{ 
    T PropertyOfMyClass 
    { 
     get { ... } 
    } 
} 

Beachten Sie, dass diese Implementierung verwendet wird, die Beschränkung auf T in der Die generische Klasse kann sich von der auf der Schnittstelle unterscheiden, solange sichergestellt ist, dass die Schnittstellenbeschränkung eingehalten wird:

public class MyOtherClass : MyClass 
{ 
} 

public class MyOtherGenericClass<T> : IMyInterface<T> where T : MyOtherClass 
{ 
    T PropertyOfMyClass 
    { 
     get { ... } 
    } 
} 
+0

Natürlich, aber meine Schnittstelle kann nicht generisch werden ... – Pitming