C# 继承的成员变量行为异常
如果我有一个这样的类:
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”!为什么会这样,如何才能让它按我想要的方式工作而不在构造函数中设置变量?
If I have a class like this:
class A {
public string fe = "A";
}
And a class that inherits from it like so:
class B : A {
public string fe = "B";
}
Visual C# will tell me that B.fe hides A.fe so I should use the new keyword. So I change class B to look like:
class B : A {
public new string fe = "B";
}
And then I have a function that takes an A (but, by virtue of inheritance, will also take a B) like this:
class D {
public static void blah(A anAObject) {
Console.Writeline(A.fe);
}
}
Even when I pass it an instance of a B object, which it will take without question, it will print "A"! Why is this, and how can I make it work how I want without setting the variable in the constructor?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这就是
override
和new
之间的区别。new
定义了一个与基类中的成员同名的成员。它不会覆盖该成员。因此,如果您有一个需要A
实例的方法,它将采用A.fe
的值,而不是派生类中同名的成员。使用带有
override
的属性来代替:That's the difference between
override
andnew
.new
defines a member which happens to have the same name as a member in the base class. It doesn't override that member. So if you have a method that expects anA
instance, it will take the value ofA.fe
and not the member in the derived class with the same name.Use a property with
override
instead:如果您希望您的
fe
成员可以被派生类覆盖,而不必使用new
关键字(这就是您看到所看到的行为的原因),只需在基类中将其声明为virtual
。那么您的代码将如下所示:请注意,这需要将
fe
设为属性,因为成员字段不能声明为virtual
。为什么您没有获得所需行为的解释是,new 关键字仅在编译时将变量声明为派生类的情况下覆盖继承的成员。如果它在编译时声明为基类(因为
anAObject
位于您的blah
方法中),则它与基类版本一致(这就是区分new
来自覆盖
)。现在,您还修改您的
blah
方法,将其输入转换为B
,从而访问您的new
< code>fe:但我不推荐这样做。
If you want your
fe
member to be overridable by derived classes without having to use thenew
keyword (which is why you're seeing the behavior you're seeing), just declare itvirtual
in the base class. Then your code would look like this:Notice that this required making
fe
a property, since member fields cannot be declaredvirtual
.The explanation for why you're not getting the behavior you want is that the
new
keyword only overrides an inherited member in the event that a variable is declared as the derived class at compile time. If it's declared as the base class at compile time (asanAObject
is in yourblah
method), it goes with the base class version (this is what differentiatesnew
fromoverride
).Now, you also could modify your
blah
method to cast its input to aB
, thereby accessing yournew
fe
:But I would not recommend this.
就是你所需要的...
AFAIK 在
D.blah()
中,对象正在转换为A
类型 &由于基值没有用virtual
关键字标记,因此它的行为类似于A
&即使类型是B
,也不是B
...is what you need...
AFAIK in the
D.blah()
the object is getting cast of typeA
& since the base value is not marked with thevirtual
keyword, it would behave asA
& not asB
even if the type isB
...