web-dev-qa-db-ja.com

C#のオーバーライドと新しいキーワードの違いは何ですか?

クラス階層でメソッドを定義する場合、C#のoverrideキーワードとnewキーワードの違いは何ですか?

69
jaywayco

次のページはあなたの質問を非常にうまく要約しています。

オーバーライドと新しいキーワードをいつ使用するかを知る

概要

Override:ベースクラスのメソッドが派生クラスでオーバーライドされると、呼び出し元のコードがtオブジェクトが派生クラスのインスタンスであることを「知っている」。

New:オーバーライドの代わりに新しいキーワードを使用すると、派生クラスのメソッドは基本クラスのメソッドをオーバーライドせず、単に非表示にしますそれ。

Newまたはoverrideのいずれも指定しない場合、結果の出力はnewを指定した場合と同じですが、コンパイラーの警告も表示されます(基本クラスのメソッドを非表示にしていることに気付かない場合があるため)メソッド、または実際にそれをオーバーライドしたいかもしれませんが、単にキーワードを含めるのを忘れていました)。

オーバーライド:基本クラスのメソッドのvirtual/abstract/overrideタイプで使用されます

New:基本クラスがメソッドをvirtual/abstract/overrideとして宣言していない場合

86
Brian Graham

newは、メソッドをオーバーライドする代わりに(まったく同じシグネチャを持つ場合と持たない場合がある)完全に新しいメソッドでメソッドをシャドウします(この場合、新しいメソッドは同じシグネチャを持つ必要があります)。つまり、ポリモーフィズムは作業。たとえば、次のクラスがあります。

class A {
    public virtual int Hello() {
        return 1;
    }
}

class B : A {
    new public int Hello(object newParam) {
        return 2;
    }
}

class C : A {
    public override int Hello() {
        return 3;
    }
}

これを行う場合:

A objectA;
B objectB = new B();
C objectC = new C();

Console.WriteLine(objectB.Hello(null)); // 2
Console.WriteLine(objectC.Hello()); // 3

objectA = objectB;

Console.WriteLine(objectA.Hello()); // 1

objectA = objectC;

Console.WriteLine(objectA.Hello()); // 3

newを使用して新しいメソッドシグネチャを定義できるため、コンパイラはAのインスタンスが実際にBのインスタンスであり、新しいメソッドB defineが使用可能である必要があります。 newは、親オブジェクトのメソッド、プロパティ、フィールド、またはイベントがvirtualで宣言されていない場合に使用できます。virtualがないため、コンパイラは継承されたメソッド。ただし、virtualおよびoverrideでは、動作します。

new;を避けることを強くお勧めします。せいぜい混乱させるだけです。なぜなら、他の何かとして認識できる名前でメソッドを定義しているからです。最悪の場合、ミスを隠し、一見不可能なバグを導入し、機能を拡張することが難しくなります。

67
Ry-

古い質問のように見えますが、別の答えを試してみましょう。

  1. new:名前が示すように、それは継承階層のファミリーの新しいメンバーであり、これはチェーンのさらに下のベースメンバーとして使用されます(仮想としてマークされている場合)。

  2. override:親クラスのメンバー実装を受け入れないことを意味し、別の方法で行います。

9
Dhananjay

次のクラス階層を考慮してください。

using System;

namespace ConsoleApp
{     
     public static class Program
     {   
          public static void Main(string[] args)
          {    
               Overrider overrider = new Overrider();
               Base base1 = overrider;
               overrider.Foo();
               base1.Foo();

               Hider hider = new Hider();
               Base base2 = hider;
               hider.Foo();
               base2.Foo();
          }   
     }   

     public class Base
     {
         public virtual void Foo()
         {
             Console.WriteLine("Base      => Foo");
         }
     }

     public class Overrider : Base
     {
         public override void Foo()
         {
             Console.WriteLine("Overrider => Foo");
         }
     }

     public class Hider : Base
     {
         public new void Foo()
         {
             Console.WriteLine("Hider     => Foo");
         }
     }
}    

上記のコードの出力は次のとおりである必要があります。

Overrider => Foo
Overrider => Foo

Hider     => Foo
Base      => Foo
  • サブクラスoverridesoverride modifierを適用することによる仮想メソッド:
  • 意図的にメンバーをhideしたい場合、その場合はサブクラスのメンバーにnew modifierを適用できます。 The new modifier does nothing more than suppress the compiler warning that would otherwise result
2
Sina Lotfi

overrideを使用すると、基本クラスの仮想メソッドをオーバーライドして、異なる実装を配置できます。newは、基本クラスの非仮想メソッドを非表示にします。

1
Daniel Mann