大象:动物....
IList<Elephant> elephants = new List<Elephant>();
IEnumerable<Animal> animalList = elephants;
Run Code Online (Sandbox Code Playgroud)
这工作正常,但..
IList<Elephant> elephants = new List<Elephant>();
IList<Animal> animalList = elephants;
Run Code Online (Sandbox Code Playgroud)
抛出错误.这是为什么?
jas*_*son 11
如果这
IList<Elephant> elephants = new List<Elephant>();
IList<Animal> animalList = elephants;
Run Code Online (Sandbox Code Playgroud)
有可能你可以这样做
animalList.Add(new Animal());
Run Code Online (Sandbox Code Playgroud)
但animalList实际上是对同一个推荐人的引用elephants.而且,由于elephants是一个IList<Elephant>你可以尝试的添加实例Animal到集合只能包含的实例Elephant.
究其原因,这是有可能IEnumerable<T>的是,IEnumerable<T>是协变的类型参数T.这是因为T只出现在界面的"out"位置IEnumerable<T>.由于您只使用了T来自的实例IEnumerable<T>,因此可以安全地IEnumerable<Derived>为类型变量分配实例IEnumerable<Base>.任何出来的东西IEnumerable<Derived>都是a Base,这就是为什么实现的东西IEnumerable<Derived>可以IEnumerable<Base>安全地使用.这就是IEnumerable<Elephant>为类型变量分配实例是安全的原因IEnumerable<Animal>.
但是你遇到了麻烦,IList<T>因为IList<T>在类型参数中不是协变的T.这里的问题是T出现在界面的"in"位置IList<T>.因此,如果您可以IList<Derived>为类型变量分配实例IList<Base>,那么您可以尝试将实例粘贴Base到IList<Base>实际上试图将实例粘贴到实例中Base的实例,IList<Derived>这显然不安全.这正是我们恰好碰到了这个问题IList<Elephant>,并IList<Animal>.
注意,IList<T>在类型参数中也不是逆变的T.这是因为T界面中出现在"out"位置IList<T>.如果你能分配的情况下IList<Base>,以类型的变量IList<Derived>,那么你可以尝试抢实例Derived走出IList<Derived>这将是试图抓住一个实例 Derived出来的实例IList<Base>,这是显然是荒谬的.