虽然可以从基类/接口继承,但为什么不能声明List<>呢
使用相同的类/接口?
interface A
{ }
class B : A
{ }
class C : B
{ }
class Test
{
static void Main(string[] args)
{
A a = new C(); // OK
List<A> listOfA = new List<C>(); // compiler Error
}
}
有别的办法吗?
至于为什么它不起作用,理解协方差和逆变可能会有所帮助。
只是为了说明为什么这不能工作,这里是对您提供的代码的更改:
void DoesThisWork()
{
List<C> DerivedList = new List<C>();
List<A> BaseList = DerivedList;
BaseList.Add(new B());
C FirstItem = DerivedList.First();
}
这可行吗?列表中的第一个项是类型“B”,但派生列表项的类型是C。
现在,假设我们真的只想创建一个泛型函数,它对实现了a的某个类型的列表进行操作,但我们不关心它是什么类型:
void ThisWorks<T>(List<T> GenericList) where T:A
{
}
void Test()
{
ThisWorks(new List<B>());
ThisWorks(new List<C>());
}
我已经阅读了整篇文章,我只是想指出对我来说似乎不一致的地方。
编译器阻止你对list执行赋值操作:
List<Tiger> myTigersList = new List<Tiger>() { new Tiger(), new Tiger(), new Tiger() };
List<Animal> myAnimalsList = myTigersList; // Compiler error
但是编译器完全可以处理数组:
Tiger[] myTigersArray = new Tiger[3] { new Tiger(), new Tiger(), new Tiger() };
Animal[] myAnimalsArray = myTigersArray; // No problem
关于任务是否安全的争论在这里站不住脚了。我对数组的赋值是不安全的。为了证明这一点,如果我继续这样做:
myAnimalsArray[1] = new Giraffe();
我得到一个运行时异常“ArrayTypeMismatchException”。如何解释这一点呢?如果编译器真的想阻止我做一些愚蠢的事情,它应该阻止我做数组赋值。