将对象转换为基本集合

时间:2011-02-17 15:07:18

标签: c# .net

我并不完全相信这是可能的,但现在就去了。我有一个返回对象的方法,虽然实际类型是Collection。现在,我可以使用

轻松地将对象转换为集合
var myCollection = myObject as Collection<MyClassA>;

但问题是Collection<MyClassA>可能是Collection<MyClassB>Collection<MyClassC>。所有这些MyClassX都是从MyBaseClass继承的,所以理想情况下我希望能够做到像这样的事情

var myCollection = myObject as Collection<MyBaseClass>;

然而,这会在投射时抛出异常。无论如何都可以这样做吗?我知道它可能在.Net 4内吗?

感谢您的帮助。

编辑: 好的 - 到目前为止的答案非常有用,但它们只解决了解决方案的第二部分 - 转换/转换集合。

我仍然不确定我最初应该如何将对象转换为集合(不使用每个可能类型的巨大if语句)

4 个答案:

答案 0 :(得分:2)

只有.NET中的IEnumerable<T>才支持此功能。请查看签名的不同之处:

IEnumerable<T>:

public interface IEnumerable<out T> : IEnumerable

Collection<T>:

public class Collection<T> : IList<T>, 
ICollection<T>, IEnumerable<T>, IList, ICollection, IEnumerable

type参数中的out关键字告诉.NET支持方差。

答案 1 :(得分:1)

替代解决方案:您可以使用接口和泛型来获得所需内容。

public interface IMyClass
{
}

public class MyClassA : IMyClass
{
}

public class MyClassB : IMyClass
{
}

public class MyClassC : IMyClass
{
}

static void Main(string[] args)
{
    var listA = new List<IMyClass>{new MyClassA{}, new MyClassA{}};
    var listB = new List<IMyClass> { new MyClassB { }, new MyClassB { } };
    var listC = new List<IMyClass> { new MyClassC { }, new MyClassC { } };

    List<IMyClass> genericList = listA.Cast<IMyClass>().ToList();
}

这样的东西将正确编译,并允许您将实现公共接口的任何类型的不同列表分配给同一个变量(在本例中为genericList

答案 2 :(得分:1)

在我访问.NET 4之前,我编写了一个实现此目的的扩展方法:

public static IEnumerable<U> CastCollection<T, U>(this IList<T> items) where U : class
{
   var collection = new List<U>();
   foreach (var item in items)
   {
      if (item is U)
      {
           var newItem = item as U;
           collection.Add(newItem);
      }
  }
  return collection;
}

您可以这样使用它:

var myCollection = myObject.CastCollection<MyClassA, MyBaseClass>();

myCollection在这种情况下将是IEnumerable<MyBaseClass>

答案 3 :(得分:0)

这不能通过整个集合来完成。但是,您可以将各个元素强制转换为新集合。看看LINQ的Cast&lt;&gt;扩展方法。