实践中的逆变 - C#

Contravariance in practice - C#

我最近阅读了有关协变和逆变的知识 - 下面的小代码示例:

public class BaseClass{
    public int x = 1;

    public static void print(BaseClass objClass)
    {
        Console.WriteLine(objClass.GetType().Name + " " + objClass.x); 
    }
}

public class DerivedClass : BaseClass{
    public int x = 2;
}

public class Program
{
    public static void Main(string[] args)
    {
        BaseClass bC = new BaseClass();
        DerivedClass dC = new DerivedClass();

        BaseClass.print(bC); //DerivedClass 1
        DerivedClass.print(bC); //DerivedClass 1
        BaseClass.print(dC); //DerivedClass 1
        DerivedClass.print(dC); //DerivedClass 1
    }
}

我的问题是 - 逆变在实践中给了我们什么?我知道我可以将 DerivedClass 的对象作为参数传递给 BaseClass 方法(其中参数是 BaseClass 类型),但这种操作有什么好处?为什么当我传递 DerivedClass 对象时 returns 我在 BaseClass 中 x 的值?

也许这是一个不好的例子来解释逆变的好处然后我会很感激另一个例子。

why when I pass DerivedClass object it returns me value of x in BaseClass ?

您正在隐藏派生的字段class。实际上 DerivedClass 两个 x 字段 - 一个来自基础 class,一个来自派生 class。由于 print 的参数是 BaseClass 类型,编译器会将 objClass.x 绑定到基 class.

中的字段

如果您有虚拟 属性 和覆盖:

public class BaseClass{
    public virtual int x {get {return 1;}}

    public static void print(BaseClass objClass)
    {
        Console.WriteLine(objClass.GetType().Name + " " + objClass.x); 
    }
}

public class DerivedClass : BaseClass{
    public override int x {get {return 2;}}
}

或者只是基字段设置为派生class中的不同值:

public class DerivedClass : BaseClass{
    public DerivedClass() {x = 2;}
}

您会看到预期的结果。