在实践中的逆变- c#

本文关键字:实践中 | 更新日期: 2023-09-27 18:17:13

我最近读了一篇关于协方差和逆变的文章,下面是一个小代码示例:

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
    }
}

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

也许这是解释逆变的好处的坏例子,那么我将感激另一个例子。

在实践中的逆变- c#

为什么当我传递DerivedClass对象时,它在BaseClass中返回x的值?

您正在隐藏派生类中的字段。实际上,DerivedClass具有两个 x字段—一个来自基类,一个来自派生类。由于print的参数类型为BaseClass,编译器将把objClass.x绑定到基类中的字段。

如果你有一个虚拟属性和重写:

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;}}
}

或者直接基字段设置为派生类中的另一个值:

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

你会看到你期望的结果。