0

このようなクラスがある場合:

class A {
    public string fe = "A";
}

そして、それを継承するクラスは次のようになります。

class B : A {
    public string fe = "B";
}

Visual C# は、B.fe が A.fe を隠していることを教えてくれるので、new キーワードを使用する必要があります。そこで、クラス B を次のように変更します。

class B : A {
    public new string fe = "B";
}

そして、次のように A を受け取る関数があります (ただし、継承により、B も受け取ります)。

class D {
    public static void blah(A anAObject) {
        Console.Writeline(A.fe);
    }
}

問題なく受け取る B オブジェクトのインスタンスを渡しても、"A" が出力されます。これはなぜですか。コンストラクターで変数を設定せずに、どのように機能させることができますか?

4

3 に答える 3

6

overrideそれがとの違いnewです。new基本クラスのメンバーと同じ名前を持つメンバーを定義します。そのメンバーをオーバーライドしません。したがって、インスタンスを期待するメソッドがある場合、同じ名前の派生クラスのメンバーではなく、Aの値を取ります。A.fe

override代わりにプロパティを使用します。

class A {
    public virtual string fe { get { return "A"; } }
}

class B : A {
    public override string fe { get { return "B"; } }
}
于 2010-05-19T16:39:35.077 に答える
2

feキーワードを使用せずに派生クラスによってメンバーをオーバーライド可能にしたい場合new(これが、表示されている動作が見られる理由です)、virtual基本クラスで宣言するだけです。次に、コードは次のようになります。

public class A
{
    public virtual string fe
    {
        get { return "A"; }
    }
}

public class B
{
    public override string fe
    {
        get { return "B"; }
    }
}

メンバ フィールドは宣言できないため、プロパティfeを作成する必要があることに注意してください。virtual

必要な動作が得られない理由の説明はnew、コンパイル時に変数が派生クラスとして宣言された場合にのみ、キーワードが継承されたメンバーをオーバーライドすることです。コンパイル時に(メソッドのように)基本クラスとして宣言されている場合、基本クラスのバージョンと一緒になりanAObjectますblah(これが との違いnewですoverride)。

ここで、メソッドを変更して入力を にキャストし、次のようにアクセスすることもできます。blahBnew fe

public static void blah(A anAObject) {
    var aBObject = anAObject as B;
    if (aBObject != null)
        Console.WriteLine(aBObject.fe); // would print "B"
    else
        Console.WriteLine(anAObject.fe); // would print "A"
}

しかし、私はこれをお勧めしません。

于 2010-05-19T16:39:15.843 に答える
1
class A {

public virtual string fe { get { return "A"; } set {} }

}

class B {
 public override string fe { get { return "B"; } set {} }
}

あなたが必要なものです...

オブジェクトのAFAIKは、ベース値がキーワードでマークされていないため、D.blah()タイプ & のキャストを取得しています。タイプが...であっても& not として動作します。AvirtualABB

于 2010-05-19T16:38:59.167 に答える