我并不完全相信这是可能的,但现在就去了。我有一个返回对象的方法,虽然实际类型是Collection。现在,我可以使用
轻松地将对象转换为集合var myCollection = myObject as Collection<MyClassA>;
但问题是Collection<MyClassA>
可能是Collection<MyClassB>
或Collection<MyClassC>
。所有这些MyClassX
都是从MyBaseClass
继承的,所以理想情况下我希望能够做到像这样的事情
var myCollection = myObject as Collection<MyBaseClass>;
然而,这会在投射时抛出异常。无论如何都可以这样做吗?我知道它可能在.Net 4内吗?
感谢您的帮助。
编辑: 好的 - 到目前为止的答案非常有用,但它们只解决了解决方案的第二部分 - 转换/转换集合。
我仍然不确定我最初应该如何将对象转换为集合(不使用每个可能类型的巨大if语句)
答案 0 :(得分:2)
只有.NET中的IEnumerable<T>
才支持此功能。请查看签名的不同之处:
public interface IEnumerable<out T> : IEnumerable
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;扩展方法。