从List <X>转换为List <Y>的语法较短?

我知道有可能将一个项目列表从一种类型转换为另一种类型(假设您的对象有一个公共静态显式运算符方法来执行转换),一次一个:


List<Y> ListOfY = new List<Y>();


foreach(X x in ListOfX)

    ListOfY.Add((Y)x);

但是不可能一次投出整个列表吗?例如,


ListOfY = (List<Y>)ListOfX;


茅侃侃
浏览 619回答 3
3回答

杨__羊羊

添加到Sweko的观点:施法之所以如此var listOfX = new List<X>();ListOf<Y> ys = (List<Y>)listOfX; // Compile error: Cannot implicitly cast X to Y是不可能的,因为List<T>它在类型T中是不变的,因此无论是否X从中派生出来Y- 这是因为List<T>定义为:public class List<T> : IList<T>, ICollection<T>, IEnumerable<T> ... // Other interfaces(注意,在此声明中,T此处键入没有其他方差修饰符)但是,如果您的设计中不需要可变集合,则可以对许多不可变集合进行向上转换,例如,如果Giraffe派生自以下内容Animal:IEnumerable<Animal> animals = giraffes;这是因为IEnumerable<T>支持协方差T- 这是有道理的,因为它IEnumerable意味着集合无法更改,因为它不支持从集合中添加或删除元素的方法。请注意out声明中的关键字IEnumerable<T>:public interface IEnumerable<out T> : IEnumerable(这里进一步解释了为什么可变集合List不能支持covariance,而不可变迭代器和集合可以。)铸造 .Cast<T>()正如其他人所提到的,.Cast<T>()可以应用于集合来投射一个新的元素集合,这些集合被投射到T,但是这样做会抛出一个InvalidCastException如果不能在一个或多个元素上强制转换(这与执行显式的行为相同)在OP的foreach循环中投射)。过滤和铸造 OfType<T>()如果输入列表包含不同的,不兼容的类型的元素,则InvalidCastException可以通过使用.OfType<T>()而不是来避免潜在的.Cast<T>()。(.OfType<>()在尝试转换之前检查元素是否可以转换为目标类型,并过滤掉不可复制的类型。)的foreach另请注意,如果OP已经写了这个:(注意显式Y y中foreach)List<Y> ListOfY = new List<Y>();foreach(Y y in ListOfX){&nbsp; &nbsp; ListOfY.Add(y);}也将尝试铸造。但是,如果不能进行强制转换,InvalidCastException则会产生结果。例子例如,给定简单的(C#6)类层次结构:public abstract class Animal{&nbsp; &nbsp; public string Name { get;&nbsp; }&nbsp; &nbsp; protected Animal(string name) { Name = name; }}public class Elephant :&nbsp; Animal{&nbsp; &nbsp; public Elephant(string name) : base(name){}}public class Zebra : Animal{&nbsp; &nbsp; public Zebra(string name)&nbsp; : base(name) { }}使用混合类型的集合时:var mixedAnimals = new Animal[]{&nbsp; &nbsp; new Zebra("Zed"),&nbsp; &nbsp; new Elephant("Ellie")};foreach(Animal animal in mixedAnimals){&nbsp; &nbsp; &nbsp;// Fails for Zed - `InvalidCastException - cannot cast from Zebra to Elephant`&nbsp; &nbsp; &nbsp;castedAnimals.Add((Elephant)animal);}var castedAnimals = mixedAnimals.Cast<Elephant>()&nbsp; &nbsp; // Also fails for Zed with `InvalidCastException&nbsp; &nbsp; .ToList();鉴于:var castedAnimals = mixedAnimals.OfType<Elephant>()&nbsp; &nbsp; .ToList();// Ellie只过滤掉大象 - 即消除了斑马。Re:隐式投射算子如果没有动态,用户定义的转换运算符仅在编译时 *使用,因此即使Zebra和Elephant之间的转换运算符可用,转换方法的上述运行时行为也不会改变。如果我们添加转换运算符以将Zebra转换为Elephant:public class Zebra : Animal{&nbsp; &nbsp; public Zebra(string name) : base(name) { }&nbsp; &nbsp; public static implicit operator Elephant(Zebra z)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; return new Elephant(z.Name);&nbsp; &nbsp; }}相反,给定上面的转换运算符,编译器将能够将以下数组的类型更改Animal[]为Elephant[],因为Zebras现在可以转换为同类的Elephants集合:var compilerInferredAnimals = new []{&nbsp; &nbsp; new Zebra("Zed"),&nbsp; &nbsp; new Elephant("Ellie")};在运行时使用隐式转换运算符*正如Eric所述,转换运算符可以在运行时通过诉诸dynamic:var mixedAnimals = new Animal[] // i.e. Polymorphic collection{&nbsp; &nbsp; new Zebra("Zed"),&nbsp; &nbsp; new Elephant("Ellie")};foreach (dynamic animal in mixedAnimals){&nbsp; &nbsp; castedAnimals.Add(animal);}// Returns Zed, Ellie
打开App,查看更多内容
随时随地看视频慕课网APP