2012-09-13 57 views
3

我有以下類層次結構。類型約束

class Header { IEnumerable<Item> Item { get; set; } .... } 
class HeaderA : Header { .... } // Item should have the type of IEnumerable<ItemA> 
class HeaderB : Header { .... } // Item should have the type of IEnumerable<ItemB> 

class Item { .... } 
class ItemA : Item { .... } 
class ItemB : Item { .... } 

是否有可能有編譯時檢查對Item的類型,以確保它的IEnumerable<ItemA>IEnumerable<ItemB>分別爲ItemAItemB?有沒有更好的設計?

回答

6

您可以更改標題類的定義傳遞類型參數給它,那麼你可以強加:

class Header<TItem> where TItem : Item { IEnumerable<TItem> Item { get; set; } } 
    class HeaderA : Header<ItemA> { } // Item should have the type of IEnumerable<ItemA> 
    class HeaderB : Header<ItemB> { } // Item should have the type of IEnumerable<ItemB> 

    class Item { } 
    class ItemA : Item { } 
    class ItemB : Item { } 
+2

你還可以考慮添加一個約束'where TItem:Item'? –

+0

這將是一個好主意,謝謝! – carlosfigueira

+0

現在完美! +1! –

2

您應該使用Generic Class

+0

我想過使用泛型。但是,'HeaderA'和'HeaderB'會添加不同的成員。 – ca9163d9

+0

看carlosfigueira的職位,你可以這樣做 – Bgi

+1

明白了。我在想Darren的答案中的設計。 – ca9163d9

1

喜歡這個

class HeaderA : Header<ItemB> { .... } 
class HeaderB : Header<ItemA> { .... } 
2

您可以使用泛型類型並將其傳遞給類。

public class Header<T> where T : Item 
{ 
    IEnumerable<T> Item { get; set; } 
} 


Header<ItemA> AHeader; 
Header<ItemB> BHeader; 

http://msdn.microsoft.com/en-US/library/sz6zd40f(v=vs.100

+0

好方法。你認爲一個約束'T:Item'會好嗎? –

+0

@Jordão - 我剛剛添加了。感謝:-) –

+0

+1也許OP真的不需要創建'Header '子類,如果他們沒有添加任何東西到基地。 –

0

如果我正確理解你的問題,你可以改變頭類的簽名來實現這一點。

class Header<ItemType> { IEnumerable<ItemType> Item {get; set;} ....} 
class HeaderA : Header<ItemA> { .... } 
class HeaderB : Header<ItemB> { .... } 

class Item { .... } 
class ItemA : Item { .... } 
class ItemB : Item { .... } 

會導致HeaderA只允許ItemA對象和HeaderB只允許ItemB對象放入它們各自的Item集合中。