快速将 List<Y> 转换为 List<X>,无需创建新的 List

Cast List<Y> to List<X> fast, without new List creation

我需要将引用基类型的列表转换为引用派生类型的列表。我不能使用 LINQ ToList,因为它会创建新列表,这对我来说很慢。在 C# 中是否有一些快速转换,可能像在 C++ 中一样。谢谢

你不能那样做。这是有原因的。考虑以下因素。

List<Animal> animals = new List<Cat>();
animals.Add(new Dog());

你在这里失去了 List<T> 的类型安全,这就是 ListT 上不协变的原因。你可以做的是将它转换为 IEnumerable<X>,因为 IEnumerable 只支持 getting 一个元素,这就是为什么 IEnumerable 在其类型参数上是协变的。

如果您只想迭代元素而不更改列表本身的任何内容,则无需创建新列表。

如果不创建新的东西,就不能将一种类型转换为另一种类型。

因此,您唯一的选择是创建一个新列表,或者拥有可以遍历现有列表并像另一种类型一样工作的东西。您可以实现自己的枚举器,或者简单地创建一个返回 IEnumerable<TypeY>yield return 内部的方法(哪种创建枚举器)。

public IEnumerable<TypeY> Convert(IEnumerable<TypeX> listX)
{
    foreach (TypeX x in listX)
    {
        yield return ConvertXToY(x);
    }
}

你试过了吗:

List<Y> listY = new List<Y>()
var listX = ListY.Select(y => new X(y));

这将创建一个您可以枚举的 IEnumerable<X>

您真的需要一个新列表吗?可以使用 LINQ OfType<T>() or Cast<T>() 吗?

var baseList = new List<BaseType>();
var derivedItems = baseList.OfType<DerivedType>();

LINQ Cast() 将成为您的朋友。但是,请注意:如果您有任何不可铸造的东西,此代码将会崩溃。

List<object> newList= new List<Object>();
newList.Add("SomeString");
foreach( string s in newList.Cast<string>())
{
    //Do something
}