4

在以下示例中,鉴于编译器知道 a是 a ,为什么我不能collectionA转换为?collectionBTItemA<T>

public class A<T>
{
}

public void Foo<TItem, T> () where TItem : A<T>
{
    var collectionA = new List<TItem>();
    var collectionB = (List<A<T>>)collectionA; // "Cannot cast" error here
}
4

3 回答 3

1

问题是它允许您将不适当的项目放入collectionA。

这是对它的简化改造,希望它可以更容易地看到问题:

假设您有(伪代码):

class Animal {...}

class Dog: Animal { Bark(){} }

class Cat: Animal { Meow(){} }

现在想象你可以这样做:

var dogs = new List<Dog>();

dogs.Add(new Dog());

dogs[0].Bark();

var animals = (List<Animal>) dogs;

然后你就可以做到这一点:

animals.Add(new Animal()); // Adds an Animal to the list 'dogs', which 'animals' references.

dogs[1].Bark(); // dogs will now have two elements, but the second isn't a dog -
                // so calling Bark() will explode.
于 2012-11-12T23:30:49.387 回答
0

我相信这是因为您正在指示系统从 to 转换List<X>List<Y>而不是说您要将列表中的每个项目从Xto 转换为Y

你可以这样做:

public class A<T>
{
}

public void Foo<TItem, T>() where TItem : A<T>
{
    var collectionA = new List<TItem>();
    var collectionB = new List<A<T>>(collectionA.ToArray()); 
}
于 2012-11-12T23:20:59.007 回答
0

你想使用

var collectionB = collectionA.OfType<List<A<T>>>(); 

或者

var collectionB = collectionA.Cast<List<A<T>>>();

第一个将忽略任何非类型List<A<T>>且不能被视为类型的内容。如果列表中有无法转换的内容,第二个将引发异常。

于 2012-11-12T23:34:38.623 回答