2016-03-01 105 views
0

我有幾個繼承類,像這樣一個抽象類:使用繼承類型的C#集合泛型參數

internal abstract class SomeBaseType {} 
internal class FirstSpecificType : SomeBaseType {} 
internal class SecondSpecificType : SomeBaseType {} 
internal class ThirdSpecificType : SomeBaseType {} 

和一類具有約束泛型類型參數:

internal class SomeCollection<T> : ICollection<SomeDataStructure> 
    where T : SomeBaseType {} 

我創建了一個List<SomeCollection<SomeBaseType>>並試圖添加各種繼承類SomeBaseType的元素,但出現以下錯誤(CS1503CS1950):

Argument 1: cannot convert from 'Namespace.SomeCollection<FirstSpecificType>' to 'Namespace.SomeCollection<SomeBaseType>' 
The best overloaded Add method 'List<SomeCollection<SomeBaseType>>.Add(SomeCollection<SomeBaseType>)' for the collection initializer has some invalid arguments 

由於​​3210是SomeBaseType,我應該可以做到這一點,對吧?這基本上與向IList<object>添加一些任意的object相同。


有關其他方面,在此錯誤表現看起來像這樣的代碼:

protected Constructor() 
{ 
    collectionOne = new SomeCollection<FirstSpecificType>(); 
    collectionTwo = new SomeCollection<SecondSpecificType>(); 
    collectionThree = new SomeCollection<ThirdSpecificType>(); 

    allCollections = new List<SomeCollection<SomeBaseType>> 
    { 
     // Each of these three collections has the error 
     collectionOne, 
     collectionTwo, 
     collectionThree 
    }; 
} 
+0

這是協方差和協方差泛型類不起作用,至少讀一次長頸鹿。 – Rahul

+1

每天都會問這個問題。再一次:長頸鹿列表不是動物列表。爲什麼?因爲你可以將一隻老虎放入動物列表中,但不能放入長頸鹿列表中。動物列表不是長頸鹿列表。爲什麼?因爲動物列表中可能已經有一隻老虎。因此,長頸鹿列表和動物列表從不兼容,因爲您可以在這兩種類型上執行的操作不同。有些動物是長頸鹿的事實是無關緊要的。 –

回答

1

這是covariance and contravariance的問題,基本上說,儘管 FirstSpecificType確實SomeBaseTypeSomeCollection<FirstSpecificType>嚴格不SomeCollection<SomeBaseType>

埃裏克利珀寫了一些美妙的articles這件事,那我建議大家:-)

+0

*約翰Skeet寫了一些神話般的文章... * ...爲什麼不鏈接該文章以及? – Rahul

+0

@Rahul - 當混淆.net大師的時候,很難找到正確的鏈接;-) – Amit

+0

感謝您的解釋和鏈接,@Amit。這幫助我找到了實現我的目標的新途徑。 – Jason