1

この背後にある設計上の根拠は何ですか:

わかった:

public class A
{
    public virtual void DoWork() { Console.WriteLine("A"); }
}
public class B : A
{
    private new void DoWork() { Console.WriteLine("B"); } //private works
}
public class C : B
{
    public override void DoWork() { Console.WriteLine("C"); }
}

違う:

public class A
{
    public virtual void DoWork() { Console.WriteLine("A"); }
}
public class B : A
{
    public new void DoWork() { Console.WriteLine("B"); } //public doesn't
}
public class C : B
{
    public override void DoWork() { Console.WriteLine("C"); }
}

とにかく非仮想メソッドが仮想メソッドのオーバーライドを妨げるのはなぜですか?

編集:詳細な説明。最初のケース: コンパイラは、メソッドがプライベート (新規) であることを確認するため、クラス C.DoWork() がクラス A.DoWork() をオーバーライドできるようにします (仮想メソッドと非仮想 (B.DoWork()) メソッドを混在させません)。2 番目のケース: コンパイラは public (new) void が宣言されていることを認識し、クラス C でのオーバーライドを任意に (?) 妨害します。シール指定子を使用することもできました。ただし、この場合、通常の非仮想メソッドを宣言するものとして public void DoWork() を記述しましたが、プライベート ケースのように仮想継承チェーンに参加することは期待していません。2番目の例では、次のことを期待しています:

A ac = new C();
ac.DoWork();

プライベートケースのように C を出力します。

4

3 に答える 3

0

最初の例では、CクラスはAをovveridesしますDoWorkBプライベートでサブクラスには表示されないDoWorkがあります)。2番目の例では、非仮想関数で非表示DoWorkにし、コンパイラが非仮想関数をオーバーライドしようとしていると文句を言います。解決策は、仮想関数のファミリーを公開することです。new virtualあなたはこれらの家族の間に分離を作成することができます。

public class B : A
{
    public new virtual void DoWork() { Console.WriteLine("B"); } //private works
}

このコードはその後

A a = new C();
a.DoWork();

プリントA

B b = new C();
b.DoWork();

プリントC

オーバーライドと新しいキーワードをいつ使用するかを知るnew virtualで、どのように使用されるかを詳しく読むことができます。のないキーワードは、とは異なるセマンティクスを持っています。メソッドシグネチャの新しいキーワードで詳細を読むことができます。newvirtualnew virtual

于 2013-01-25T09:42:53.153 に答える
0

最初のAケースでは、クラス関数ではなくクラス関数をオーバーライドしているためBです

public class A
{
    public virtual void DoWork() { Console.WriteLine("A"); }
}
public class B : A
{
    private new void DoWork() { Console.WriteLine("B"); } //private works
}
public class C : B
{
    public override void DoWork() { Console.WriteLine("C"); } //OVERRIDES A.DoWork()
}

基本クラスの/メソッドをオーバーライドすることはできません。 virtualabstract

于 2013-01-25T09:46:48.313 に答える
0

以下のコードで

public class A
{
    public virtual void DoWork() { Console.WriteLine("A"); }
}
public class B : A
{
    private new void DoWork() { Console.WriteLine("B"); } //private works
}
public class C : B
{
    public override void DoWork() { Console.WriteLine("C"); }
}

newB クラスの DoWork() メソッドがクラス A の DoWork() メソッドのバージョンであることをコンパイラに伝えています。ただし、overrideDoWork のバージョンを B で非公開として宣言しているため、C で DoWork を使用できます。newこれにより、コンパイラはそのメソッドが外部に公開されていないと想定します。

ただし、これには、

public class A
{
    public virtual void DoWork() { Console.WriteLine("A"); }
}
public class B : A
{
    public new void DoWork() { Console.WriteLine("B"); } //public
}
public class C : B
{
    public override void DoWork() { Console.WriteLine("C"); }
}

コンパイラに新しいバージョンのメソッド DoWork() を伝えていますが、言語の設計中に設定されたルールに従って/ /非メソッドoverrideにすることはできないため、コンパイラの観点からは少し間違っています。overrideabstractvirtualoverriden

だからこそ、あなたのコードはあるケースではエラーを出し、他のケースではエラーを出さないと思います。

于 2013-01-25T09:55:13.433 に答える