2013-04-02 167 views
1

我有以下類別: 爲什麼我的派生類不能傳遞給基類?

public class Item 
{ 
} 

public class ItemCollection<TItem> : ICollection<TItem> where TItem : Item, new() 
{ 
} 

我有兩個派生類:

public class Feature : Item 
{ 
} 

public class Features : ItemCollection<Feature> 
{ 
} 

我有一個經理級的管理這樣的集合:

public class ItemCollectionManager<TCollection> where TCollection : ItemCollection<Item>, new() 
{ 
} 

我試着使用此課程:

public class FeatureManager : ItemCollectionManager<Features> 
{ 
} 

,但是這會導致:

「之類Features必須是爲了在泛型類ItemCollectionManager<TCollection>使用它作爲TCollection轉換爲ItemCollection<Item>」。

而且如前面提到的,

Features是-一個ItemCollection<Feature>

Feature是-一個Item

我不認爲接口是這項任務的理想解決方案,但如果提供了原因,我願意改變。

如果有人可以建議我在做什麼錯誤,將非常感激。

謝謝。

回答

2

你不能做......

ItemCollection<Feature> features = ...; 
ItemCollection<Item> items = features; 

這是關於仿製藥variance(協方差和逆變即是) - 而且它僅支持接口,委託 - 而且只提供他們這樣設計的 (用in/out裝飾 - 並遵守隨之而來的規則)。例如IEnumerable<>是(如果你查找它的定義,你會看到out)。欲瞭解更多細節,我認爲最好閱讀更多...

How is Generic Covariance & Contra-variance Implemented in C# 4.0?
Understanding Covariant and Contravariant interfaces in C#
http://msdn.microsoft.com/en-us/library/dd799517.aspx

在你的情況,你可以設計一個IItemCollection<out T>interface) - 即(理論上)可能支持你所需要的鑄造。但它必須是read-only有點簡化,並不完全正確,但更容易這樣想 - 規則有點複雜)。

既然你命名它「收集」我假設它不只是枚舉,查看項目 - 也就是說,如果你有一個排序(要求input parameters - 即contra-variance)的Add與衝突的「協方差「,您需要upcasting。還有其他任何參數可能不允許你的接口進行協變。


我也做了一些相關的其他職位...

How to make generic class that contains a Set of only its own type or subtypes as Children?

C# generic handlers, what am I misunderstanding?

+0

+1爲協方差和鏈接。我不知道你可以用in/out來裝飾類型參數。 –

+0

@ MalcolmO'Hare不客氣 - 是的,它可能在某些情況下很有用 – NSGaga

1

您需要在ItemCollectionManager,TItem上添加一個通用參數。

我相信你的ItemCollectionManager類定義應該看起來像這樣。

public class ItemCollectionManager<TCollection, TItem> where TCollection : ItemCollection<TItem>, new(), 
where TItem : Item 
    { 
    } 

您在FeatureManager類中定義現在它是完全可以接受添加它繼承ItemTCollection任何類,因爲在TCollection,唯一的限制的方式是,它包含Item類型的類。集合Features只接受Feature繼承Feature類型的類或類。由於不能將基本類型Item添加到Features,因此不應編譯。

+1

實現它的方式產生進一步問題的路線,我不相信供應TItem是必要的因爲無論如何它只是一個'Item'。但是,如果這是必需的,請你能解釋一下爲什麼? –

+0

我已經添加了一些解釋。如果它仍然不清楚,那麼讓我知道,我會盡力解釋它。 –

相關問題