不能用接口实现逆变?

时间:2010-04-23 01:56:05

标签: c# contravariance

我正处于开始掌握逆变的地步,虽然我正在尝试找出可以使用接口的优势。显然我错过了什么。

这是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那样的简短语法方式来委托?

1 个答案:

答案 0 :(得分:2)

逆向性是为什么这适用于接口的原因。方法调用允许参数类型逆变(和返回类型协方差)。

没有多种方法可以解决同样的问题。

考虑到有时你无法控制类结构。如果您无法更改Dog的定义怎么办?如果没有类型差异,你的任务突然变得更加困难。

协方差和逆变不是问题 已解决,它们是语言特征,如泛型类型。您可以使用泛型类型执行的所有操作,您可以在.NET 1.x中执行泛型类型之前,并且仍然可以执行大量的装箱和转换。你应该?这完全取决于您的要求。