簡體   English   中英

C#繼承的成員變量行為異常

[英]C# Inherited member variables behaving undexpectedly

如果我有這樣的課程:

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”! 為什么會這樣,又如何在不構造函數中設置變量的情況下使它按我的意願工作呢?

那就是overridenew之間的區別。 new定義一個成員,該成員恰好與基類中的成員具有相同的名稱。 它不會覆蓋該成員。 因此,如果您有一個期望A實例的方法,它將采用A.fe的值,而不是派生類中具有相同名稱的成員。

使用帶有override的屬性:

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

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

如果您希望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關鍵字僅覆蓋繼承的成員。 如果在編譯時將其聲明為基類(因為blah方法中包含anAObject ),那么它將與基類版本一起使用(這是newoverride區別)。

現在,您還可以修改blah方法以將其輸入轉換為B ,從而訪問new 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"
}

但是我不建議這樣做。

class A {

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

}

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

這就是你需要的...

AFAIK在D.blah()對象是越來越類型的鑄造A &由於基值不與標記virtual關鍵字,這將表現為A &不如B即使類型是B ...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM