2010-03-14 13 views
5

in .NET Framework, gibt es einen allgemeinen IEnumerable<T> Schnittstelle, die aus den nicht-generic IEnumerable erbt, und sie haben beide eine GetEnumerator() Methode. Der einzige Unterschied zwischen diesen beiden GetEnumerator() ist der Rückgabetyp. Jetzt habe ich ein ähnliches Design, aber wenn ich den Code zu kompilieren, die Compiler sagte:IEnumerable.GetEnumerator() und IEnumerable <T> .GetEnumerator()

MyInterface<T>.GetItem() ‚verbirgt geerbt Mitglied‘ MyInterface.GetItem()‘. Verwenden Sie das neue Schlüsselwort, wenn das Ausblenden beabsichtigt war.

Die MyInterface<T>.GetItem() gibt einen konkreten Typ T zurück, während MyInterface.GetItem() den Typ System.Object zurückgibt.

Also ich denke, wenn die BCL-Team-Jungs das. NET-Framework kompilieren, werden sie die gleiche Warnung erhalten.

Ich denke Compiler Warnungen zu haben ist nicht gut, was denkst du? Und wie kann ich dieses Problem lösen? Ich meine, ich möchte den konkreten Typ T beim Aufruf der MyInterface<T>.GetItem() nicht nur eine Instanz des Typs System.Object bekommen.

Vielen Dank im Voraus! :-)

Ergänzung: Ich sage die Schnittstellen theirselves: IMyInterface erbt von IMyInterface, und sie haben beide die GetItem() -Methode (die IMyInterface.GetItem() zurückkehrt T eingeben, während IMyInterface. GetItem() liefert den Typ System.Object). Das Problem ist, dass, wenn unser Code nur diese beiden Schnittstellen haben, das heißt, keine abgeleiteten konkreten Klassen, werden wir die Compiler-Warnung nach dem Kompilieren des Quellcodes auftreten.

Antwort

10

Sie tun es nicht, weil sie eine Version als explizite Interface-Methode Implementierung kompilieren. Es sieht wie folgt aus:

public class SomeClassThatIsIEnumerable<T> : IEnumerable<T> 
{ 
    public IEnumerator<T> GetEnumerator() 
    { 
     // return enumerator. 
    } 

    IEnumerator IEnumerable.GetEnumerator() 
    { 
     return ((IEnumerable<T>)this).GetEnumerator(); 
    } 
} 

Was diese Art der Konstruktion ist die erste Methode GetEnumerator die Standardmethode, während die andere Methode GetEnumerator nur wird zugänglich machen ist, wenn der Anrufer zuerst SomeClassThatIsIEnumerable wirft den Typen IEnumerator, so dass es vermeidet das Problem.

Edit: auf der Grundlage der Ergänzung oben, würden Sie das neue Schlüsselwort verwenden möchten:

public interface IMyInterface 
{ 
    object GetObject(); 
} 

public interface IMyInterface<T> : IMyInterface 
{ 
    new T GetObject(); 
} 

// implementation: 

public class MyClass : IMyInterface<string> 
{ 
    public string GetObject() 
    { 
     return "howdy!"; 
    } 

    object IMyInterface.GetObject() 
    { 
     return GetObject(); 
    } 
} 
+0

Hi, ich sage das nicht, bitte seht meinen "Nachtrag" in der Post. Danke :) –

+0

+1, obwohl Sie keine Zugriffsebene für eine explizite Schnittstellenimplementierung angeben können – erikkallen

+0

@Dylan: Verwenden Sie das neue Schlüsselwort, wie der Compiler empfiehlt. Siehe meine Änderungen oben. –

3

Der Unterschied ist, dass IEnumerable<T> und IEnumerable Schnittstellen sind. In einem konkreten Typ, der beide Schnittstellen implementiert, muss mindestens eine davon explizit implementiert werden.

Bei einer konkreten Vererbung müssen Sie das neue Schlüsselwort verwenden, um anzugeben, dass Sie die Methode vom Basistyp überschreiben möchten. Beim Anwenden des neuen Schlüsselworts wird die Methode nicht vererbt. Dies bedeutet, dass myTypeInstance.Method die auf MyType definierte Methode aufruft, während ((MyBaseType) myTypeInstance).Method die auf dem Basistyp definierte Methode aufruft.

public interface Interface1 { 
    object GetItem(); 
} 

public interface Interface2<T> : Interface1 { 
    T GetItem(); 
} 

public class MyBaseType : Interface1 { 
    public object GetItem() { 
     // implements Interface1.GetType() 
     return null; 
    } 
} 

public class MyType<T> : Interface1, Interface2<T> { 
    public new T GetItem() { 
     // Implements Interface2<T>.GetItem() 
     return default(T); 
    } 

    object Interface1.GetItem() { 
     // implements Interface1.GetItem() 
     return this.GetItem(); // calls GetItem on MyType 
    } 
} 

var myType = new MyType(); 
var myTypeResult = myType.GetItem(); // calls GetItem on MyType 
var myBaseTypeResult = new ((MyBaseType) myType).GetItem(); // calls GetItem on MyBaseType 
+0

Hallo, die Interface2 erbt von Interface1 in meinem senario, dann werden Sie die Compiler-Warnung erhalten. –

+0

Sollte keinen Unterschied machen, solange eine der GetItem-Methoden explizit implementiert ist, d. H. Mit Interface.GetItem. – AxelEckenberger

+0

Hallo, es wird eine Compiler-Warnung geben, wenn ich nicht das Schlüsselwort "new" verwende. Bitte beachten Sie meine Ergänzung in der Post.:) –

Verwandte Themen