2015-02-05 194 views
9

比方說,我有一個如下的C#接口:爲什麼實現具有類型約束的泛型接口的泛型類需要重複這些約束?

public interface IInterface<T> where T : SomeClass 
{ 
    void InterfaceMethod(); 
} 

,並按如下SomeClass的定義:

public class SomeClass 
{ 
    public void SomeMethod(); 
} 

現在,我想定義接口的實現,這將不編譯:

public class InterfaceImpl<T> : IInterface<T> 
{ 
    public void InterfaceMethod() 
    { 
     T test = default(T); 
     test.SomeMethod(); //Gives Error 
    } 
} 

之前,我將其更改爲:

public class InterfaceImpl<T> : IInterface<T> where T : SomeClass 
{ 
    public void InterfaceMethod() 
    { 
     T test = default(T); 
     test.SomeMethod(); //Compiles fine 
    } 
} 

從界面中類型約束是否也是「繼承的」(不是我所知道的正確的詞)是不合理的?

+1

如果沒有指定,他們可能已經「默認」實現了。但實際的語法允許重新定義約束(繼承,new()關鍵字等),這很好。 – AFract 2015-02-05 18:32:10

回答

9

該類不需要重複這些約束,它需要提供一種類型,即滿足接口的約束條件。有這樣做的幾種方法:

  • 它可以提供滿足約束條件的特定類型或
  • 它可以放置在一個通用的類型比接口所期待的其自身的限制,或
  • 它可以從接口重複約束。

關鍵的一點是,在TInterfaceImpl<T>屬於InterfaceImpl,以便放置在任何T約束必須是InterfaceImpl自己。

+0

非常好的和明確的解釋,最後一句對我來說至關重要:)知道你的答案,我唯一不明白的是爲什麼C#允許我創建一個不會執行你提到的任何事情的類回答?比如說,它是一些抽象類,它不調用T的方法 - 我可以在不對T進行任何約束或指定類型的情況下編譯它,這將滿足接口的約束。 – 2015-02-05 18:47:46

+1

@BartekEborn我不確定你的意思。在通用接口有約束的情況下,實現它的類需要提供一個兼容的參數,而不管實現類是否抽象([demo-not-compile](http://ideone.com/WG9pR1) )。我相信你的意思是別的。你能做一個演示來展示你的意思嗎?你可以點擊演示中的「fork」,然後根據需要進行修改。 – dasblinkenlight 2015-02-05 18:57:35

+0

這正是我的意思。我不好,我爲你的努力感到抱歉。我信任Intellisense,在這種情況下沒有突出顯示錯誤(儘管它在前面已經提到過)。經過實際測試,我感到羞愧:(再次抱歉! – 2015-02-05 19:04:36