8

次のコードを検討してください。

public abstract class Test1
{
    public object Data { get; set; }
}

public abstract class Test2<T> : Test1
{
    public T Data { get; set; }
}

これにより、次の警告が生成されます。

「Test2.Data」は、継承されたメンバー「Test1.Data」を非表示にします。非表示が意図されている場合は、new キーワードを使用します。

なぜこれは単なる警告であり、「new」キーワードを追加するとどのような影響がありますか?

私のテストによると、「new」キーワードが追加されると、違いは見つかりません。

誤解しないでいただきたいのですが、私はすべて明示的であることに賛成ですが、「新規」を追加することのメリットについて知りたいと思っていました。

それが何であるかについての私の唯一の考えは次のとおりです。

  • 人間の可読性の向上
  • 避けられないことを長い道のりで理解するためにコンパイラが残されていない場合、実行時にいくらかの節約
4

4 に答える 4

21

newキーワードが持つ唯一の効果は、警告を削除することです。キーワードを使用していないときに警告を受け取る目的は、new本当にメソッドをオーバーライドするつもりだったときに誤ってメソッドをシャドウするのを防ぐことです。

于 2009-08-10T13:41:02.557 に答える
3

new基本クラスのメソッドまたはプロパティを非表示にするために使用されます。これは、オーバーライドするようなものではありません。メンバーは、非表示の基本クラスメンバーと同じ署名を持つ必要はなく、ポリモーフィズムに関与しません。

例 :

class A
{
    public virtual void Test()
    {
        Console.WriteLine("A.Test");
    }
}

class B : A
{
    public new void Test()
    {
        Console.WriteLine("B.Test");
    }
}

class B : A
{
    public override void Test()
    {
        Console.WriteLine("C.Test");
    }
}

public static void Main(string[] args)
{
    A aa = new A();
    aa.Test(); // Prints "A.Test"

    A ab = new B();
    ab.Test(); // Prints "A.Test" because B.Test doesn't overrides A.Test, it hides it

    A ac = new C();
    ac.Test(); // Prints "C.Test" because C.Test overrides A.Test

    B b = new B();
    b.Test(); // Prints "B.Test", because the actual type of b is known at compile to be B
}
于 2009-08-10T13:48:54.763 に答える
2

エラーとしてレポート警告をオンにします。これにより、newとoverrideの使用法をより明確にする必要があります。

于 2009-08-10T13:45:54.720 に答える
1

派生クラス メソッドを同じ名前の基本クラス メソッドのオーバーライドとみなすべきかどうかは、多くの場合、派生クラス メソッドの作成者が基本クラス メソッドとそれに関連付けられたコントラクトを認識しており、派生メソッドを作成したかどうかに依存します。その契約を履行するためのクラスメソッド。派生クラスのメソッドが基本クラスのメソッドと同じ名前と署名を持つほとんどの場合、派生クラスのメソッドは基本クラスの契約を満たすことを意図していますが、展開された基本クラスの作成者が名前を追加した場合同じ名前が派生クラスで他の目的に使用されていることに気付かなければ、派生クラス メソッドの作成者は、その時点では存在しなかった基本クラス メソッドの契約に準拠するようにメソッドを記述したとは推定できません。 .

異なるメソッドがいつクラスに追加されたかを C# が判断できる一般的な手段がないため、派生クラス メソッドの作成者が、同じ名前の基底クラス メソッドの存在について何かを知っていたかどうかをコンパイラが知る方法はありません。ただしnew、派生クラス メソッドの作成者が、またはoverride修飾子を使用して、基本クラス メソッドの存在を認識しているかどうかをコンパイラに明示的に示している場合を除きます。

修飾子 (またはその欠如) を次のように解釈することをお勧めします。

  • なし -- 作成者は基本クラス メソッドの存在を認識していないため、その契約を履行することを期待できません。

  • new-- 作成者は基本クラス メソッドを認識しており、何らかの理由でこのメソッドを実行しないように記述しています。

  • override-- 作成者は基本クラス メソッドとそのコントラクトを認識しており、それを満たすためにこのメソッドを作成しました。

コンパイラがデフォルトnewで警告付きで想定する理由は、基本クラスのメソッドが存在する前にメソッドが派生クラスに追加された場合、作成者が基本クラスの契約を認識しているとは期待できないためです。まだ存在していなかったコントラクトを履行するつもりであったとは考えられませんが、基本クラスのメソッドの後に派生クラスのメソッドが記述されている場合、作成者は通常、ベースを履行するつもりがない限り、別の名前を選択する必要があります。 -クラス契約、または契約を履行せずに同じ名前を使用する特定の理由があります。コンパイラは、どのメソッドが最初に記述されたかを判断できないため、どの動作が適切であるかを知る方法がありません。

于 2015-06-23T21:58:57.007 に答える