【问题标题】:C# Generics, casting generic list to known parent class?C#泛型,将泛型列表转换为已知的父类?
【发布时间】:2013-05-14 14:03:39
【问题描述】:

我正在尝试使用泛型将对象列表投射到其父级。我有这样的课程:

Entity
  Node
  OtherClass

Node/OtherClass 继承自 Entity。 我想做的是这样的:

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...
}

我可以使用 FieldInfo 参考获取该字段,但我无法转换列表。字段值是节点引用列表,但似乎无法将其转换为实体列表,这应该是可能的,因为它继承自实体。

转换为节点列表可以,但我也希望代码能够获取 OtherClass 的列表。将对象转换为 List 对象,然后将每个单独的对象转换为 Entity 也是行不通的。

我尝试使用 MakeGenericType,这可能是解决方案的一部分,但经过一段时间的尝试后我无法让它工作。

感谢您的宝贵时间!

【问题讨论】:

  • A List&lt;Node&gt; 继承自 List&lt;Entity&gt;,即使 Node 确实继承自 Entity。您必须创建一个新列表和AddRange 第一个。
  • 这是一个常见问题。将 List 转换为 List 不起作用,不应该起作用。您可以将OtherNode : Entity 添加到 List,但 List 不能容纳 OtherNode。 (尽管有强制转换,列表仍然是一个 List。)转换是不安全的,因此是非法的。
  • 一个更安全(合法)的转换是从 List 到 IEnumerable,仅供参考。

标签: c# .net c#-4.0 generics reflection


【解决方案1】:

其他选项的变体,但使用协方差:

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

这依赖于IEnumerable&lt;T&gt; 的通用协方差,因此仅适用于 C# 4+ 和 .NET 4+。

虽然List&lt;Node&gt; 不是List&lt;Entity&gt;,但它一个IEnumerable&lt;Entity&gt;...上面的代码利用了这一点。

当然,如果您只需要迭代,则不需要List&lt;Entity&gt;

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

但如果您确实需要创建一个List&lt;Entity&gt;,在IEnumerable&lt;Entity&gt; 上调用ToList() 应该没问题。

【讨论】:

    【解决方案2】:

    你可以这样做

    林克:

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

    【讨论】:

    • 感谢您的建议。但问题是我不想硬编码只能处理派生,而是我希望能够通用处理所有实体派生
    • 那么请接受 Jon Skeet 的回答..\
    【解决方案3】:

    您可以使用IEnumerable 并在循环中进行强制转换:

    // list of derived objects
    IEnumerable nodes = fieldValue;
    
    // process base fields
    foreach (Entity toEnt in nodes)
    {
        // Code using toEnt using its Entity attributes...
    }
    

    您只需确保节点是Entity 派生的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-12-02
      • 2015-11-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-01
      • 1970-01-01
      相关资源
      最近更新 更多