[英]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.