我正处于开始掌握逆变的地步,虽然我正在尝试找出可以使用接口的优势。显然我错过了什么。
这是c#4示例
class Dog : Animal {
public Dog(string name) : base(name) { }
}
class Animal {
string _name;
public Animal(string name) {
_name = name;
}
public void Walk() {
Console.WriteLine(_name + " is walking");
}
}
Action<Animal> MakeItMove = (ani) => { ani.Walk(); };
Action<Dog> MakeItWalk = MakeItMove;
MakeItWalk(new Dog("Sandy"));
在c#
的早期版本中使用的相同示例class Dog : Animal {
public Dog(string name) : base(name) { }
}
class Animal : IAnimal {
string _name;
public Animal(string name) {
_name = name;
}
public void Walk() {
Console.WriteLine(_name + " is walking");
}
}
interface IAnimal {
void Walk();
}
Action<IAnimal> MakeItMove = (ani) => { ani.Walk(); };
Action<IAnimal> MakeItWalk = MakeItMove;
MakeItWalk(new Dog("Sandy"));
这些可能不是最好的例子,但我似乎仍然无法“得到它”。在动作委托中定义的 关键字是否只是像lambda那样的简短语法方式来委托?
答案 0 :(得分:2)
逆向性是为什么这适用于接口的原因。方法调用允许参数类型逆变(和返回类型协方差)。
没有多种方法可以解决同样的问题。
考虑到有时你无法控制类结构。如果您无法更改Dog
的定义怎么办?如果没有类型差异,你的任务突然变得更加困难。
协方差和逆变不是问题 已解决,它们是语言特征,如泛型类型。您可以使用泛型类型执行的所有操作,您可以在.NET 1.x中执行泛型类型之前,并且仍然可以执行大量的装箱和转换。你应该?这完全取决于您的要求。