2010-03-14 60 views
5

在.NET框架中,有一個通用的接口IEnumerable<T>其中來自未通用IEnumerable繼承,並且它們都具有一個GetEnumerator()方法。這兩個GetEnumerator()之間唯一的區別是返回類型。 現在我有一個類似的設計,但是當我編譯代碼,編譯器說:IEnumerable.GetEnumerator()和IEnumerable <T> .GetEnumerator()

MyInterface<T>.GetItem()「隱藏繼承成員」 MyInterface.GetItem()」。如果需要隱藏,請使用新關鍵字。

MyInterface<T>.GetItem()返回一個具體類型T,而MyInterface.GetItem()返回類型System.Object。

所以我想如果BCL團隊的人編譯.net框架,他們會得到相同的警告。

我覺得有編譯器警告不好,你怎麼看?我該如何解決這個問題?我的意思是,當調用MyInterface<T>.GetItem()時,我不想只是System.Object類型的一個實例。

在此先感謝! :-)

補充: 我說的接口過問:IMyInterface的從 IMyInterface的繼承,並且它們都具有的GetItem()方法(IMyInterface.GetItem()返回一個類型T,而IMyInterface的。 GetItem()返回類型System.Object)。問題是,如果我們的代碼只有這兩個接口,也就是沒有派生的具體類,編譯源代碼後我們會遇到編譯器警告。

回答

10

它們並不是因爲它們將一個版本編譯爲顯式接口方法實現。它看起來像這樣:

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

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

這是什麼類型的構造確實是使第一GetEnumerator方法成爲默認的方法,而其他GetEnumerator方法是唯一可如果主叫方先蒙上SomeClassThatIsIEnumerable的類型的IEnumerator,所以它避免了這個問題。

編輯:基於上面的補充,你會想使用new關鍵字:

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

嗨,我不是說這個,請在​​帖子中看到我的「補充」。謝謝:) – 2010-03-15 11:54:24

+0

+1,即使你不能爲明確的接口實現指定訪問級別 – erikkallen 2010-03-15 12:18:48

+0

@Dylan:根據編譯器建議使用new關鍵字。看到我上面的編輯。 – 2010-03-15 12:18:53

3

區別在於IEnumerable<T>IEnumerable是接口。在一個具體的類型中,它實現了兩個接口,其中至少有一個必須被明確地實現。

在具體類型繼承中,您必須使用new關鍵字來指示您要覆蓋基類型的方法。當應用新關鍵字時,該方法不會被繼承。這意味着myTypeInstance.Method將調用在MyType上定義的方法,而((MyBaseType) myTypeInstance).Method將調用在基本類型上定義的方法。

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

嗨,我在塞納里奧,從接口1的接口2 繼承,那麼你會得到編譯器警告。 – 2010-03-15 11:55:30

+0

只要其中一個GetItem方法明確實現,即使用Interface.GetItem,應該沒有區別。 – AxelEckenberger 2010-03-15 20:53:09

+0

嗨,會有一個編譯器警告,除非我使用「新」關鍵字。請在帖子中查看我的補充內容。:) – 2010-03-16 05:57:22

相關問題