【问题标题】:Cast a List of object without using LINQ在不使用 LINQ 的情况下转换对象列表
【发布时间】:2011-04-19 17:10:00
【问题描述】:

来自我在这里的问题:Cast in List object

我使用 LINQ 接受了答案:

myA = myB.Cast<A>().ToList();

我有一个问题:我们有任何其他不使用 LINQ 的解决方案,因为我的应用程序使用的是 .NET Framework 2.0。

更新: 如果我有几个从 myA 派生的类 myB、myC、myD、myE...,我需要一个可以将列表转换为列表的函数(T 可能是 myB 或 myC 或 myD,...)以避免重复相同的代码. The function input is a list&lt;T&gt; and the function output is a list&lt;myA&gt;.

谢谢。

【问题讨论】:

  • 您可以编写自己的版本,循环、转换和收集到类型化集合中。
  • 我更新了我的问题。请帮我。谢谢。

标签: c# .net .net-2.0


【解决方案1】:

一个简单的foreach 就可以解决问题(为了便于阅读,我将类命名为 Foo 和 Bar)

myFoos = new List<Foo>();
foreach (Bar bar in myBars)
{
  myFoos.Add((Foo)bar);
}

问题编辑后:

要将多个子类的列表转换为基类,我将创建一个名为 BaseCollection 的类,而不是从 List 继承,因为通常还需要对列表进行一些其他操作。一些有用的方法可能是:

 public class BaseCollection : List<Base>
 {
    public static BaseCollection ToBase<T>(IEnumerable<T> source) where T: Base
    {
       BaseCollection result = new BaseCollection();
       foreach (T item in source)
       {
          result.Add(item);
       }
       return result;
     }

    public static List<T> FromBase<T>(IEnumerable<Base> source) where T: Base
    {
       List<T> result = new List<T>();
       foreach (Base item in source)
       {
          result.Add((T)item);
       }
       return result;
     }


    public static List<T> ChangeType<T, U>(List<U> source) where T: Base where U:Base
    {        
        List<T> result = new List<T>();        
        foreach (U item in source)        
        {           
            //some error checking implied here
            result.Add((T)(Base) item);        
        }        
        return result;      
    }  

    ....
    // some default printing
    public void Print(){...}         
    ....
    // type aware printing
    public static void Print<T>(IEnumerable<T> source) where T:Base {....}
    ....
 }

这将使我能够轻松地将任何后代与基类集合进行转换,并像这样使用它们:

List<Child> children = new List<Child>();
children.Add(new Child { ID = 1, Name = "Tom" });
children.Add(new Child { ID = 2, Name = "Dick" });
children.Add(new Child { ID = 3, Name = "Harry" });

BaseCollection bases = BaseCollection.ToBase(children);
bases.Print();

List<Child> children2 = BaseCollection.FromBase<Child>(bases);
BaseCollection.Print(children2);

【讨论】:

  • +1:但是你不应该需要 (Foo)bar 演员,因为 bar 必须是 Fooanyway。
  • 没有。这个解决方案很糟糕。如果我有几个派生自 myA 的类 myB、myC、myD、myE...,我需要一个可以将 list 转换为 list 的函数(T 可能是 myB 或 myC 或 myD,... ) 以避免重复相同的代码。谢谢。
  • 那就创建一个泛型函数吧!
  • @Nick,它可能,但这样它既适用于 Dog -> Animal,也适用于 Animal -> Dog(前提是这些动物确实是狗)
  • @Lu Lu:这只是一个代码 sn-p,如果你真的有几个类,并且经常使用它们的列表,我会将它们硬输入到 FooCollection、BarCollection、BazCollection 类中,这将是直接castable,避免到处重复这种代码(将编辑答案)。
【解决方案2】:

对于 .NET 2.0,您可以编写自己的 Cast 方法,使用 Linq 代码作为指导:

public static class EnumerableHelper
{
    public static IEnumerable<TResult> Cast<TResult>(IEnumerable source)
    {
        IEnumerable<TResult> enumerable = source as IEnumerable<TResult>;
        if (enumerable != null) return enumerable;
        if (source == null) throw new ArgumentNullException("source");        
        foreach(object element in source)
        {
            yield return (TResult) element;
        }
    }
}

然后按如下方式使用:

myA = new List<A>(EnumerableHelper.Cast<A>(myB));   

【讨论】:

  • +1,使用引用的 LINQ 实现的源代码来实现它的一部分总是一个好主意。
【解决方案3】:
    public static List<B> Cast<A,B>(List<A> aLIst) where A : B
    {
        List<B> ret = new List<B>( );

        foreach (A a in aLIst)
        {
            ret.Add(a);
        }

        return ret;
    }    

【讨论】:

    猜你喜欢
    • 2015-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-15
    • 1970-01-01
    • 1970-01-01
    • 2016-03-01
    • 1970-01-01
    相关资源
    最近更新 更多