C# 为什么可以';接口类型的列表是否接受继承接口的实例?
鉴于以下类型:C# 为什么可以';接口类型的列表是否接受继承接口的实例?,c#,list,types,interface,C#,List,Types,Interface,鉴于以下类型: public interface IPrimary{ void doBattle(); } // an ISecondary "is" an IPrimary public interface ISecondary : IPrimary { } // An implementation of ISecondary is also an IPrimary: internal class SecondaryImpl : ISecondary { // Required,
public interface IPrimary{ void doBattle(); }
// an ISecondary "is" an IPrimary
public interface ISecondary : IPrimary { }
// An implementation of ISecondary is also an IPrimary:
internal class SecondaryImpl : ISecondary
{
// Required, since this is an IPrimary
public void doBattle(){ }
}
为什么我不能这样做
List<IPrimary> list = new List<ISecondary>();
它是为了保护你不出错。列表实例(对象)需要辅助实例。并不是每一个小学都是中学。然而,人们的期望是,一个primary列表可以容纳任何primary。如果我们能把次要事物的清单当作主要事物的清单:坏东西
事实上,数组确实允许这样做,如果您弄错了,在运行时会出错
为什么我不能这样做<代码>列表=新列表()代码>
假设您有一个定义如下的方法:
public void PopulateList(List<IPrimary> listToPopulate)
{
listToPopulate.Add(new Primary()); // Primary does not implement ISecondary!
}
public void PopulateList(列表填充)
{
listToPopulate.Add(new Primary());//Primary未实现ISecondary!
}
如果将列表作为参数传递给它,会发生什么
List
不能从List
中赋值的错误是编译器帮助您摆脱这些麻烦的方法。列表类型在其泛型参数中不协变的原因,即List
不是List
的子类型,是因为它们是读写的。在您的扩展示例中,您的方法AcceptList
可以执行list。添加(x)
,其中x
是i首要的
,而不是i次要的
请注意,IEnumerable
是正确的协变数组,而数组的类型是协变的(您可以尝试执行上面的操作),但出于同样的原因,这并不合理-向集合添加元素将在运行时失败。公共类
public class Animal
{
...
}
public class Cat: Animal
{
public void Meow(){...}
}
List<Cat> cats = new List<Cat>();
cats.Add(new Cat());
cats[0].Meow(); // Fine.
List<Animal> animals = cats; // Pretend this compiles.
animals.Add(new Animal()); // Also adds an Animal to the cats list, since animals references cats.
cats[1].Meow(); // cats[1] is an Animal, so this explodes!
{
...
}
公猫:动物
{
公共void Meow(){…}
}
列表猫=新列表();
添加(新的Cat());
猫[0]。喵喵();//好的
列出动物=猫;//假设这是编译的。
动物。添加(新动物());//还将动物添加到猫列表中,因为动物引用猫。
猫[1]。喵喵();//猫[1]是一种动物,所以它爆炸了!
这就是为什么。您想看看“C#中的泛型协方差”。和List List=newlist()“代码>是没有意义的,即使你可以这么做。”@GrantThomas好的,可能有点简化;但是someListOfTypePrimary.AddRange(someProvider.getListOftypeSecondary())呢代码>?有什么原因不应该发生这种情况吗?我认为应该允许这样做,因为AddRange
采用IEnumerable
类型,它支持协方差-IEnumerable
可以在任何地方使用IEnumerable
。谢谢+一个富有洞察力和幽默感的例子。:)谢谢,很好的解释。请欣赏关于数组的旁注。
public void PopulateList(List<IPrimary> listToPopulate)
{
listToPopulate.Add(new Primary()); // Primary does not implement ISecondary!
}
public class Animal
{
...
}
public class Cat: Animal
{
public void Meow(){...}
}
List<Cat> cats = new List<Cat>();
cats.Add(new Cat());
cats[0].Meow(); // Fine.
List<Animal> animals = cats; // Pretend this compiles.
animals.Add(new Animal()); // Also adds an Animal to the cats list, since animals references cats.
cats[1].Meow(); // cats[1] is an Animal, so this explodes!