C# 与成员隐藏

发布于 2024-08-17 04:30:34 字数 327 浏览 11 评论 0原文

在下面的例子中,会发生什么?

class Base {
    public int abc = 3;
}

Class Derived : Base {
    public int abc = 2;
}

static void Main() {
   Derived blah = new Derived();
   Console.WriteLine(blah.abc);
}

我确信您会在控制台上看到“2”,但我正在阅读(和看到)的内容与此相反......

为什么您会看到“3”而不是“2”?我认为派生类的成员“隐藏”了基类的相同成员......

in the below example, what would happen?

class Base {
    public int abc = 3;
}

Class Derived : Base {
    public int abc = 2;
}

static void Main() {
   Derived blah = new Derived();
   Console.WriteLine(blah.abc);
}

I'm sure you would see '2' on your console, but what I'm reading (and seeing) opposes that...

Why would you see '3' instead of '2'? I thought members of derived classes 'hid' the same members of base classes...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

岁月静好 2024-08-24 04:30:34

好吧,您有一些编译器错误,但这里是基于您的示例的更正版本。

class Base {
    public int abc = 3;
}

class Derived : Base {
    public int abc = 2;
} 

static void Main(string[] args)
{
    Derived foo = new Derived();
    Console.WriteLine(foo.abc);
    Base bar = new Derived();
    Console.WriteLine(bar.abc);
}

第一行将输出 2。第二行将输出 3。原因是,除非您显式重写基类的成员,否则它将仅适用于具体类的实例。

在派生类中,您实质上使用的是 new修饰符关键字而不明确使用它。 new 关键字隐藏一个基成员,但是,如果将具体类强制转换为其基类型,则新属性不会被使用,也无法访问,直到它被使用为止。再次被“贬低”到具体阶级。

在第二个示例中,Derived 类被强制转换为 Base,因此它将使用 Base abc 属性。如果您要使用覆盖关键字 ,那么第二行也会输出 2

编辑:请记住,为了允许在 Derived 类上使用override,您需要标记 Base.abcvirtual 关键字 。另外,您不能将字段虚拟。您需要使用属性来使用虚拟 关键字。不过,您不应该一开始就公开字段,因此这通常不是问题。

Well, you have a few compiler errors, but here is a corrected version based on your example.

class Base {
    public int abc = 3;
}

class Derived : Base {
    public int abc = 2;
} 

static void Main(string[] args)
{
    Derived foo = new Derived();
    Console.WriteLine(foo.abc);
    Base bar = new Derived();
    Console.WriteLine(bar.abc);
}

The first line will output a 2. The second line will output a 3. The reason why is because, unless you explicitly override a member of a base class, it will only apply to instances of the concrete class.

In your derived class, you're essentially using the new modifier keyword without explicitly using it. The new keyword hides a base member, however if the concrete class is cast as its base type, the new property doesn't get used and can't be accessed until it is "cast-down" to the concrete class again.

In the second example, the Derived class is cast as a Base, so it will use the Base abc property. If you were to use the override keyword, then the second line would also output a 2.

Edit: Keep in mind that in order to be allowed to use override on the Derived class, you need to mark Base.abc with the virtual keyword. Also, you can't make fields virtual. You need to use Properties to use the virtual keyword. You shouldn't be exposing fields to begin with though, so this is generally never a problem.

衣神在巴黎 2024-08-24 04:30:34

忽略代码中明显且大量的错误:O,您的断言“我确信您会在控制台上看到'2'”是正确的,您会的,我也会的!

您应该真正使用

class Derived : Base {
    public new int abc = 2;
}

如果隐藏继承值是您的意图,

Ignoring the obvious and numerous errors in your code :O, your assertion that "I'm sure you would see '2' on your console" is correct, you will, and I do!

You should really user

class Derived : Base {
    public new int abc = 2;
}

if hiding the inherited value is your intention

屋顶上的小猫咪 2024-08-24 04:30:34

当然您会看到2。您为什么认为您会看到 3 ?

但你会收到警告:

“Derived.abc”隐藏继承的成员
'基地.abc'。使用 new 关键字,如果
有意隐藏。

所以你可以解决它:

class Derived : Base {
    public new int abc = 2;
}

Of course you will see 2. Why did you think that you will see 3 ?

But you will get a warning:

'Derived.abc' hides inherited member
'Base.abc'. Use the new keyword if
hiding was intended.

So you can solve it doing:

class Derived : Base {
    public new int abc = 2;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文