2

型リファレント オブジェクトに基づくメソッド オーバーライドの場合は、メソッド呼び出しが決定されます。オブジェクトのタイプに基づいてメソッドを非表示にする場合、メソッド呼び出しが決定されます。

オーバーライド+非表示でのメソッド呼び出しの決定を誰かが説明してくれますか?

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 は、ランタイム ポリモーフィズムのために Derived.DoIt を呼び出します。

#4 は Derived.DoIt を呼び出しました。これは、d が Dreived 型であるためです (メソッドの隠蔽)。

しかし、なぜ #3 が Derived.DoIt を呼び出したのでしょうか。

c# でオーバーライドと非表示を行う場合の呼び出しシーケンスは何ですか。

前もって感謝します

4

3 に答える 3

1

#3 はBase型のインスタンスであるためです。ここでは、 の最後の派生メソッドがクラスにBase存在するため、呼び出されています。Derived

new/ メソッドの隠蔽 / シャドウイングは、メソッドのオーバーライドとは異なります。つまり、オーバーライドは基本メソッドをカスタマイズすることを意味newし、同じメソッド名に対して異なる実装を提供することを意味します。

于 2016-05-08T09:23:13.513 に答える
1

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 
于 2016-05-08T09:27:07.770 に答える
0

#3 は Derived.DoIt() を呼び出します。これは、メソッドが非表示になっているだけであるためです。適切なキャストを使用すると、外部から呼び出すことができます。の変数 b は Base 型であるため、Base で使用可能なメソッドにアクセスしています。これは Derived によって上書きされるものなので、結果は Derived.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();
    }
}
于 2016-05-08T09:19:23.223 に答える