[英]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”! 為什么會這樣,又如何在不構造函數中設置變量的情況下使它按我的意願工作呢?
那就是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"; } }
}
如果您希望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
),那么它將與基類版本一起使用(這是new
與override
區別)。
現在,您還可以修改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.