2013-05-14 75 views
1

我試圖將對象的列表轉換爲使用泛型的父對象。我有類如:C#泛型,將通用列表轉換爲已知的父類?

Entity 
    Node 
    OtherClass 

其中Node/OtherClass繼承自實體。 我想要做的是這樣的:

Type toType = typeof(Node); // Actually not gotten this way 
Object fieldValue = field.GetValue(item); 
List<Entity> entities = (List<Entity>)fieldValue; 

foreach (Entity toEnt in entities) 
{ 
    // Code using toEnt using its Entity attributes... 
} 

我能夠得到使用字段信息參考的領域,但我無法投列表。字段值是節點引用列表,但它似乎無法將其轉換爲實體列表,因爲它從實體繼承,所以應該可能。

鑄造到節點列表反而工作,但我也希望代碼能夠採取其他類列表。它也不適用於轉換爲對象列表,然後將每個對象轉換爲實體。

我嘗試使用MakeGenericType,這可能是解決方案的一部分,但經過一段時間的嘗試後,我無法使其工作。

謝謝你的時間!

+2

'List '*不會從'List '繼承,即使'Node'確實從'Entity'繼承。您必須創建一個新列表,並在第一個列表中添加「AddRange」。 – 2013-05-14 14:09:46

+0

這是一個常見問題。 Casting列表到列表不會和*不應該*工作。您可以將「OtherNode:Entity」添加到列表,但List 不能包含OtherNode。 (儘管演員,名單*仍然*列表。)轉換是不安全的,因此是非法的。 – 2013-05-14 14:13:17

+0

作爲FYI,更安全(合法)的轉換是從列表到IEnumerable 。 – 2013-05-14 14:14:28

回答

6

上的其他選項的變化,但使用的協方差:

var sequence = (IEnumerable<Entity>) field.GetValue(item); 
var entities = sequence.ToList(); 

這依賴於IEnumerable<T>通用協方差,所以只能用C#4+和.NET 4+工作。

雖然List<Node>不是List<Entity>,它一個IEnumerable<Entity> ...其中,上述代碼利用的優點。

當然,如果你只需要迭代,你不需要一個List<Entity>

var sequence = (IEnumerable<Entity>) field.GetValue(item); 
foreach (var entity in sequence) 
{ 
    ... 
} 

但是,如果你做需要創建一個List<Entity>,上IEnumerable<Entity>調用ToList()應該罰款。

+0

這很好,謝謝很多! =) – ChewToy 2013-05-14 14:18:44

4

你能做到這一點

的Linq:

List<Base> listOfBase = new List<Derived>().Cast<Base>().ToList(); 
+0

感謝您的建議。但事情是,我不想硬編碼只能處理派生,而是我想能夠處理所有的實體衍生物一般 – ChewToy 2013-05-14 14:12:44

+0

然後請與Jon Skeet的答案去.. \ – 2013-05-14 14:15:21

0

您可以使用IEnumerable,做演員的循環:

// list of derived objects 
IEnumerable nodes = fieldValue; 

// process base fields 
foreach (Entity toEnt in nodes) 
{ 
    // Code using toEnt using its Entity attributes... 
} 

你只需要確保該節點衍生出來的Entity

相關問題