两种简单的C#继承方法产生不同的输出

两种简单的C#继承方法产生不同的输出,c#,inheritance,C#,Inheritance,以下代码提供不同的输出。有人能解释为什么吗 代码显示在下面。结果集显示在它下面。 我已经编译了《企业VS 2015,更新2》的代码。 我在Win7上运行它 请注意,我在两个示例中都使用了阴影(隐藏)。这个问题不涉及阴影与覆盖的使用。问题是“为什么阴影会导致两种不同的输出?” 以下是编译和运行的代码,为调用对象的两种不同方法提供了不同的结果: 以下是结果集: 您不应该在继承方案public new void Display()中使用new。 当您说new而不是override时,您将取消此方

以下代码提供不同的输出。有人能解释为什么吗

代码显示在下面。结果集显示在它下面。 我已经编译了《企业VS 2015,更新2》的代码。
我在Win7上运行它

请注意,我在两个示例中都使用了阴影(隐藏)。这个问题不涉及阴影与覆盖的使用。问题是“为什么阴影会导致两种不同的输出?”

以下是编译和运行的代码,为调用对象的两种不同方法提供了不同的结果:



以下是结果集:



您不应该在继承方案
public new void Display()
中使用new。 当您说new而不是override时,您将取消此方法的继承。 要获得正确的行为,您应该写:

internal class FooBarParent
    {
        public virtual void Display()
        {
            Console.WriteLine("FooBarParent::Display");
        }
    }

    internal class FooBarSon : FooBarParent
    {
        public override void Display()
        {
            Console.WriteLine("FooBarSon::Display");
        }
    }

    internal class FooBarDaughter : FooBarParent
    {
        public override void Display()
        {
            Console.WriteLine("FooBarDaughter::Display");
        }
    }
执行此操作时:

var fooBarFamily = new FooBarParent();
您(隐式)将
fooBarFamily
声明为
FooBarParent
类型

由于
Display
方法不是虚拟的,因此不存在虚拟调度。因此,您调用的方法仅由声明的
fooBarFamily
类型决定

因此,在对
fooBarFamily.Display
的每次调用中,无论实例的运行时类型是什么,您都在调用
FooBarParent.Display()

相反,当您为每个实例提供其自己的
var
时,该类型将被推断为您正在创建的实例的类型:

var fooBarSon = new FooBarSon();

为您提供类型为
fooBarSon
fooBarSon
,因此您正在调用
fooBarSon.Display()
;同样地,对于
fooBarDaughter

你知道什么是
虚拟的吗?你什么时候“必须”使用它?使用
var
就是一个例子。在
FooBar
中,
fooBarFamily
是作为
FooBarParent
的一个实例静态键入的。因此,当您将其设置为和
FooBarSon
的实例时,它不会改变。因此,它仍然会调用
FooBarParent.Display()
。我不认为这是一个重复的问题,与Ivan Stoev在C#中隐藏和重写之间的区别是一样的?5个答案。请注意,我认为最好使用虚拟。然而,我不是在问“如何最好地编写代码”。我在问,为什么这段代码会给出不同的输出?Msdn说:“覆盖修饰符扩展了基类方法,而新修饰符隐藏了它”()。如果他想隐藏原始代码,为什么不使用new呢?我知道有更好的方法来编写上面的代码。我不是在问“我怎样才能得到我想要的结果”。我在问“为什么我会得到两个不同的结果?”
var fooBarFamily = new FooBarParent();
var fooBarSon = new FooBarSon();