快速将 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>
的类型安全,这就是 List
在 T
上不协变的原因。你可以做的是将它转换为 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
}
我需要将引用基类型的列表转换为引用派生类型的列表。我不能使用 LINQ ToList,因为它会创建新列表,这对我来说很慢。在 C# 中是否有一些快速转换,可能像在 C++ 中一样。谢谢
你不能那样做。这是有原因的。考虑以下因素。
List<Animal> animals = new List<Cat>();
animals.Add(new Dog());
你在这里失去了 List<T>
的类型安全,这就是 List
在 T
上不协变的原因。你可以做的是将它转换为 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
}