我知道可以将一列项目从一种类型强制转换为另一种类型(假设你的对象有一个公共静态显式操作符方法来执行强制转换),如下所示:
List<Y> ListOfY = new List<Y>();
foreach(X x in ListOfX)
ListOfY.Add((Y)x);
但是是否可以一次强制施放整个列表?例如,
ListOfY = (List<Y>)ListOfX;
我知道可以将一列项目从一种类型强制转换为另一种类型(假设你的对象有一个公共静态显式操作符方法来执行强制转换),如下所示:
List<Y> ListOfY = new List<Y>();
foreach(X x in ListOfX)
ListOfY.Add((Y)x);
但是是否可以一次强制施放整个列表?例如,
ListOfY = (List<Y>)ListOfX;
当前回答
dynamic data = List<x> val;
List<y> val2 = ((IEnumerable)data).Cast<y>().ToList();
其他回答
如果X起源于Y,你也可以使用ToList<T>方法而不是Cast<T>方法
listOfX.ToList<Y>()
直接强制转换变量ListOfY = (List<Y>)ListOfX是不可能的,因为它需要List<T>类型的co/逆变,并且在每种情况下都不能保证。请继续阅读,看看这个铸造问题的解决方案。
虽然能够编写这样的代码看起来很正常:
List<Animal> animals = (List<Animal>) mammalList;
因为我们可以保证每个哺乳动物都是动物,这显然是一个错误:
List<Mammal> mammals = (List<Mammal>) animalList;
因为不是每一种动物都是哺乳动物。
但是,使用c# 3及以上版本,您可以使用
IEnumerable<Animal> animals = mammalList.Cast<Animal>();
这让选角变得容易一些。这在语法上等同于逐个添加代码,因为它使用显式强制转换将列表中的每个哺乳动物强制转换为一个Animal,如果强制转换不成功,则会失败。
如果您希望对强制转换/转换过程有更多的控制,可以使用List<T>类的ConvertAll方法,该方法可以使用提供的表达式来转换项。它还有一个额外的好处,它返回一个List,而不是IEnumerable,所以不需要. tolist()。
List<object> o = new List<object>();
o.Add("one");
o.Add("two");
o.Add(3);
IEnumerable<string> s1 = o.Cast<string>(); //fails on the 3rd item
List<string> s2 = o.ConvertAll(x => x.ToString()); //succeeds
如果X真的可以转换为Y,你应该能够使用
List<Y> listOfY = listOfX.Cast<Y>().ToList();
一些需要注意的事情(H/T评论者!)
你必须包括使用System.Linq;来获得这个扩展方法 这将强制转换列表中的每个项——而不是列表本身。调用ToList()将创建一个新的List<Y>。 此方法不支持自定义转换运算符。(参见为什么Linq强制转换<> helper不能与隐式强制转换操作符一起工作?) 此方法不适用于具有显式操作符方法的对象(framework 4.0)
您可以使用List<Y>。ConvertAll<T>([从Y到T的转换器]);
这不是这个问题的答案,但它可能对一些人有用:正如@SWeko所说,由于协方差和逆变性,List<X>不能在List<Y>中强制转换,但List<X>可以强制转换为IEnumerable<Y>,甚至使用隐式强制转换。
例子:
List<Y> ListOfY = new List<Y>();
List<X> ListOfX = (List<X>)ListOfY; // Compile error
but
List<Y> ListOfY = new List<Y>();
IEnumerable<X> EnumerableOfX = ListOfY; // No issue
最大的优点是它不会在内存中创建一个新的列表。