繁体   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