【问题标题】:C# Cast Object to List of Base ClassC# 将对象转换为基类列表
【发布时间】:2011-12-27 04:46:08
【问题描述】:

我有以下类结构:

public class Fruit { }
public class Apple : Fruit { }

然后我使用 .net 框架中的一个方法,该方法从作为对象返回的类中获取属性值。所以,

// values will be of type List<Apple>
object values = someObject.GetValue()

我现在有这个 List 类型的值对象,我想将它转换为 Fruit 类型的 List。我尝试了以下方法,但没有成功。

List<Fruit> fruits = values as List<Fruit>;

有谁知道如何将一个对象转换为它的基类列表?

更新:在强制转换时,我不知道 values 对象是 List 类型,我只知道它应该是从 Fruit 继承的类型的 List。

【问题讨论】:

    标签: c# casting base-class


    【解决方案1】:

    问题在于List&lt;Apple&gt;List&lt;Fruit&gt; 不是协变的。您首先必须转换为 List&lt;Apple&gt;,然后使用 LINQ 的 Cast 方法将元素转换为 Fruit

    List<Fruit> fruits = values is List<Apple> ? 
        (values as List<Apple>).Cast<Fruit>().ToList() :
        new List<Fruit>();
    

    如果您事先不知道类型并且不需要修改列表(并且您使用的是 C# 4.0),您可以尝试:

    IEnumerable<Fruit> fruits = values as IEnumerable<Fruit>;
    

    或者,我猜,如果你需要一个列表:

    List<Fruit> fruits = (values as IEnumerable<Fruit>).ToList();
    

    【讨论】:

    • 我不知道 values 对象是 Apple 类型。我只知道它应该是继承基类 Fruit 的类型。
    • @Nick Olsen - 如果您使用 C# 4.0,则更新选项。
    • 我正在使用 C# 4.0 并将其转换为 IEnumerable 工作!有没有理由为什么会这样并且不能将其转换为 List
    • @Nick Olsen - 说来话长。从第一部分开始阅读到第十一部分:blogs.msdn.com/b/ericlippert/archive/tags/…
    • 如果你传递给一个方法,找到了一种方法来做到这一点。创建一个泛型方法。 .net 4. void method(List list) where T:BaseClass{ }。这样你就可以传递方法(列表),其中列表是基类;
    【解决方案2】:

    你应该试试linq cast method。 Cast 方法将返回您要转换为的类型的 IEnumerable...

       List<Fruit> fruits = null;
       if ( values is List<Apples> ) 
         fruits = ((List<Apples>)values).Cast< fruits >.ToList();
    

    【讨论】:

    • 但是 values 是 object 类型的,我很确定 Cast 扩展方法只适用于 IEnumerable 类型。
    • 如果不首先将值转换为适当的类型(它是一个对象...不实现 IEnumerable),这将无法工作。
    【解决方案3】:

    既然你说你知道对象是一个水果列表,但你不知道它是哪个水果的列表,你可以这样做:

    List<Fruit> fruits = ((IEnumerable)values).Cast<Fruit>().ToList();
    

    如果您使用的是 .NET 4(不包括 Silverlight 4),则可以使用 Justin Niessner 的解决方案:

    List<Fruit> fruits = ((IEnumerable<Fruit>)values).ToList();
    

    最后,如果有一个已知水果(Apple 或其他)静态类型的调用站点,则可以使用通用解决方案。这意味着要对代码进行相当多的更改,这样您就不再使用反射来获取值了。

    另一种通用方法是创建通用方法并在运行时通过在对象上调用 GetType() 来构造它,但这可能是治疗比疾病更糟糕的情况。

    【讨论】:

    • 谢谢,这实际上是唯一帮助我的事情。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多