2013-01-10 45 views
-5

這是我原來的線程: C# generic inheritance and covarianceC#泛型繼承和協方差部分2

在剛剛我只讀接口,我想的傳承工作。

public delegate Boolean EnumerateItemsDelegate<out ItemType>(ItemType item); 

public interface IReadOnlyCollection<out ItemType> 
{ 
    Boolean ContainsItem(ItemType item); 
    Array CopyToArray(); 
    void EnumerateItems(EnumerateItemsDelegate<ItemType> enumerateDelegate); 

    UInt32 Count { get; } 
    UInt32 Capacity { get; } 
} 

像這樣,除非它編譯:-P

這是我想什麼去上班:

IReadOnlyCollection<String> s; 
IReadOnlyCollection<Object> o = s; 
+0

順便提一句,'ItemType'應該叫做'T'。 – SLaks

+0

而不是讓'CopyToArray'返回'Array',讓它返回'ItemType []',這樣它的強類型。 – Servy

+2

這個問題似乎沒有任何問題。 「我想要繼承工作」不是一個問題。如果你想要一個答案,將其重寫爲一個問題。編譯器是正確的;此代碼不是類型安全的。 –

回答

5

似乎沒有要在這個問題上的任何問題,所以我會提出幾個問題來回答。

什麼是協變轉換?

讓我們假設我們有一些類型的FruitAppleBanana具有明顯的關係; Apple是一種Fruit,依此類推。

協變轉換是其中類型參數的可轉換性意味着泛型類型的可轉換性的轉換。如果Apple可轉換爲Fruit,並Bowl<Apple>可轉換爲Bowl<Fruit>,然後Bowl<T>在T.


什麼是逆變轉換協變?

甲逆變轉換是一種協變轉換該反轉方向,而不是保存。如果Eater<Fruit>可轉換爲Eater<Apple>然後Eater<T>是T.


逆變我要怎樣接口或委託爲在其類型參數的協變或逆變?

協變類型參數標記爲out,逆變類型參數標記爲in

這是爲了助記符:協變接口通常在輸出位置出現類型參數,並且反向接口有類型參數出現在輸入位置。


String可轉換爲Object。我怎樣才能讓IReadOnlyCollection<String>兌換成IReadOnlyCollection<Object>

請在T.馬克它outIReadOnlyCollection<T>協變。


考慮下面的代碼:

delegate void Action<in T>(T t); 
interface IFoo<in X> 
{ 
    void M(Action<X> action); 
} 

爲什麼編譯器說,這是不是有效?

因爲它是無效的。讓我們看看爲什麼。

class Foo : IFoo<Fruit> 
{ 
    public void M(Action<Fruit> action) 
    { 
    action(new Apple()); // An apple is a fruit. 
    } 
} 
... 
IFoo<Fruit> iff = new Foo(); 
IFoo<Banana> ifb = iff; // Contravariant! 
ifb.M(banana => { banana.Peel(); }); 

按照邏輯。這個程序通過一個蘋果作爲Banana.Peel()的「這個」,這顯然是錯誤的。

編譯器知道這可能發生,因此不允許首先聲明接口。


我應該怎麼做,如果我有變化的問題嗎?

您應該先閱讀我關於該功能設計和實現的文章。從底部開始;它們列出以相反的順序爲:

http://blogs.msdn.com/b/ericlippert/archive/tags/covariance+and+contravariance/

如果您仍然有問題,那麼你應該在這裏張貼問題,實際上包含的問題,而不是讓人們猜測什麼真正的問題是。

+0

你是對的我真的想出來,現在只是告訴編譯器,ContainsItem不關心類型,只要它是一個引用類型... –

+0

@RyanBrown看到我上面的評論。要告訴編譯器你不關心'ContainsItem'方法的參數類型,使它成爲一個新的泛型類型,它繼承自'ItemType'如下:'bool ContainsItem (T item)where T :ItemType;'。 – jam40jeff