【问题标题】:How to cast a list of a base type to list of the derived type如何将基类型列表转换为派生类型列表
【发布时间】:2013-03-07 23:01:35
【问题描述】:

从派生类到基类似乎有很多问题,但我的问题是如何将基类型列表转换为派生类型列表?

public class MyBase {
    public int A;
}

public class MyDerived : MyBase {
    public int B;
}

public void MyMethod() {
    List<MyBase> baseCollection = GetBaseCollection();
    List<MyDerived> derivedCollection = (List<MyDerived>)baseCollection; // Which doesn't work
}

我最终得到的解决方案不是很优雅。

public class MyBase {
    public int A;
}

public class MyDerived {
    public int B;
    public MyBase BASE;
}
public void MyMethod() {
    List<MyBase> baseCollection = GetBaseCollection();
    List<MyDerived> derivedCollection = new List<MyDerived>();
    baseCollection.ForEach(x=>{
        derivedCollection.Add(new derivedCollection(){ BASE = x});
    });
}

一定有更好的办法……

【问题讨论】:

  • 那不是派生类。
  • 不能简单地将 List 转换为 List,因为 List 可能包含大象或兔子,而这些是来自 List[i] 的非法返回值。
  • 感谢您的解释,我发现这很困难的全部原因是我对 MY CODE 的假设,即 baseCollection 只包含 MyBase 对象。

标签: c# .net linq


【解决方案1】:

你可以使用Linq方法OfType&lt;MyDerived&gt;(),例如:

List<MyDerived> derivedCollection = baseCollection.OfType<MyDerived>().ToList();

它会删除所有不是MyDerived类的项目

【讨论】:

  • 这个返回0个项目,baseCollelction只包含MyBase的项目。
  • MyDerived 类的任何项目对象吗?如果不是,则不能将 MyBase 但不是 MyDerived 的对象转换为 MyDerived 类。
  • 这就是我的领悟:(
  • 如果您想创建新的MyDerived 对象并将BASE 属性设置为原始对象,您可以使用List&lt;MyDerived&gt; derivedCollection = baseCollection.Select(myBase =&gt; new MyDerived {BASE = myBase}).ToList();
【解决方案2】:

铸造基类列表到派生类列表基本上是非类型安全的。

您的代码复制一个基础列表到一个派生列表。

您可以更简单地做到这一点:

List<MyDerived> derivedCollection = baseCollection.ConvertAll(x => new derivedCollection(){ BASE = x});

【讨论】:

    【解决方案3】:
    using System.Linq;
    
    // with exception in case of cast error
    var derivedCollection = baseCollection.Cast<MyDerived>().ToList();
    
    // without exception in case of cast error
    var derivedCollection = baseCollection.OfType<MyDerived>().ToList();
    

    【讨论】:

    • cast 失败,OfType 返回 0 个项目(baseCollelction 只包含 MyBase 的项目)
    • 哪个是正确的,永远不能将 MyBase 转换为 MyDerived,我的错误是认为 OO 不够。
    【解决方案4】:

    试试这个:

    public class MyBase
    {
        public int A;
    }
    
    public class MyDerived : MyBase
    {
        public int B;
    
        public MyDerived(MyBase obj)
        {
            A = obj.A;
        }
    }
    
    
    public void MyMethod() {
        List<MyBase> baseCollection = GetBaseCollection();
        List<MyDerived> derivedCollection = baseCollection.Select(x => new MyDerived(x)).ToList();
    }
    

    【讨论】:

      猜你喜欢
      • 2016-02-26
      • 2022-10-14
      • 2016-11-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多