C# 方法隐藏和重写调用决策

C# 方法隐藏和重写调用决策,c#,overriding,method-hiding,C#,Overriding,Method Hiding,在基于类型referent对象重写方法的情况下,将决定hold方法调用。 在基于对象类型的方法隐藏的情况下,将决定方法调用 有谁能解释一下重写+隐藏中调用decision的方法吗 public class Base { public virtual void DoIt() { } } public class Derived : Base { public override void DoIt()

在基于类型referent对象重写方法的情况下,将决定hold方法调用。 在基于对象类型的方法隐藏的情况下,将决定方法调用

有谁能解释一下重写+隐藏中调用decision的方法吗

public class Base
    {
        public virtual void DoIt()
        {
        }
    }

    public class Derived : Base
    {
        public  override void DoIt()
        {
        }
    }

    public class Derived1 : Derived
    {
        public new void DoIt()
        {
        }
    }
    class Program
    {
        static void Main(string[] args)
        {

            Base b = new Derived();
            Derived d = new Derived();
      #1    b.DoIt();                      // Calls Derived.DoIt
      #2    d.DoIt();                     // Calls Derived.DoIt
            b = new Derived1();
            d = new Derived1();
      #3    b.DoIt();                      // Calls Derived.DoIt
      #4    d.DoIt();
}
}
#1和#2调用派生的.DoIt,因为运行时多态性

#4调用了Derived.DoIt,因为d的类型为Dreived(方法隐藏)

但是为什么#3调用了Derived.DoIt

如果在c#中进行过度隐藏和隐藏,调用顺序是什么

提前感谢

#3次调用派生的.DoIt(),因为该方法只是隐藏的,如果使用适当的强制转换,它仍然可以在外部调用。的变量b是Base类型,因此您正在访问Base可用的方法。这是通过“派生”覆盖的结果,因此您的结果是派生的.DoIt。如果您有一个类型为Derived1的变量,并在那里调用DoIt,那么就会调用Derived1.DoIt

public class Base
{
    public virtual void DoIt()
    {
        Console.WriteLine("Base.DoIt was called!");
    }
}

public class Derived : Base
{
    public override void DoIt()
    {
        Console.WriteLine("Derived.DoIt was called!");
    }
}

public class Derived1 : Derived
{
    public new void DoIt()
    {
        Console.WriteLine("Derived1.DoIt was called!");
    }
}
class Program
{
    static void Main(string[] args)
    {

        Base b = new Derived();
        Derived d = new Derived();
        Console.WriteLine("#1");
        b.DoIt();                      
        Console.WriteLine("#2");
        d.DoIt();                     
        b = new Derived1();
        d = new Derived1();
        Console.WriteLine("#3");
        b.DoIt();                    
        Console.WriteLine("#4");
        d.DoIt();
        Console.WriteLine("#5");
        Derived1 e = new Derived1();
        e.DoIt();
        Console.ReadKey();
    }
}
因为#3是
Base
类型的一个实例。这里,
Base
的最后一个派生方法驻留在
derived
类中,因此调用它


new
/方法隐藏/隐藏不同于方法重写,因为重写意味着您正在自定义基本方法,而
new
意味着您只是为相同的方法名称提供了不同的实现。

在方法重写中,它取决于运行时要使用哪种类型的方法调用,但方法隐藏或隐藏是编译时的事情,编译器在编译时知道要调用哪个类型的方法,当您在方法签名的派生类型中使用
new
关键字而不是重写时,这意味着,若使用基类的引用调用,它将调用基类实现;若使用派生类引用,它将调用派生类方法实现

派生类实现对基类隐藏

如果你这样写:

b = new Derived1();
b.DoIt() // (run-time) will call Dervied method implementation as Dervied has overridden 
        // so calling via base reference will call overridden implementation if any
       //otherwise base class implementation will get called

Derived1 d1 = (Derived1)b;
d1.DoIt(); // (compile time) will call Derived1 method implementation due to hiding in Derived1
Derived d = (Derived)b;
d.DoIt(); // (run-time) will call Derived method implementation due to override 

您可以这样想:
Derived1
有两个
DoIt
方法-一个继承自
Base
类,另一个在
Derived1
本身中声明。当您在Base或派生类型的实例上调用DoIt时,它们只知道一个DoIt方法,而不知道另一个,因此会调用这个DoIt方法。