我需要使用对基类型的引用来转换List以列出对派生类型的引用。我无法使用LINQ ToList,因为它会创建新列表,这对我来说很慢。在C#中有一些快速演员,也许就像在C ++中一样。感谢。
答案 0 :(得分:4)
你做不到。这是有原因的。请考虑以下事项。
List<Animal> animals = new List<Cat>();
animals.Add(new Dog());
您在此处失去List<T>
的类型安全性,这就是List
在T
上不协变的原因。您可以做的是将其强制转换为IEnumerable<X>
,因为IEnumerable仅支持获取元素,这就是IEnumerable
对其类型参数有协变性的原因。
如果您只想迭代元素,则无需创建新列表,也无需更改任何有关列表的内容。
答案 1 :(得分:2)
如果不创建新内容,则无法将一种类型转换为另一种类型。
因此,您唯一的选择是创建一个新列表,或者具有可以迭代现有列表并且像另一个列表类似的行为。您可以实现自己的枚举器,或者只是创建一个返回IEnumerable<TypeY>
和yield return
的方法(在哪种类型下创建枚举器)。
public IEnumerable<TypeY> Convert(IEnumerable<TypeX> listX)
{
foreach (TypeX x in listX)
{
yield return ConvertXToY(x);
}
}
答案 2 :(得分:2)
你试过了吗?
List<Y> listY = new List<Y>()
var listX = ListY.Select(y => new X(y));
这将创建一个可以枚举的IEnumerable<X>
答案 3 :(得分:2)
你真的需要一个新名单吗?您可以使用LINQ OfType<T>()
或Cast<T>()
吗?
var baseList = new List<BaseType>();
var derivedItems = baseList.OfType<DerivedType>();
答案 4 :(得分:2)
LINQ Cast()将成为你的朋友。但是,要小心:如果你有任何不可投射的东西,这段代码就会崩溃。
List<object> newList= new List<Object>();
newList.Add("SomeString");
foreach( string s in newList.Cast<string>())
{
//Do something
}