C# - 调用基类中的方法

发布于 2024-11-30 11:29:21 字数 694 浏览 0 评论 0原文

我有 2 个类:

public class A
{
    public void WriteLine(string toWrite) { Console.WriteLine(toWrite); }
}

public class B : A
{
    public new void WriteLine(string toWrite) { Console.WriteLine(toWrite + " from B"); }
}

在我的代码中,我执行以下操作:

B writeClass = new B();
writeClass.WriteLine("Output"); // I expect to see 'Output from B'
A otherClass = (A)writeClass;
otherClass.WriteLine("Output"); // I expect to see just 'Output'

我认为这会起作用,因为 多态性。

但是,它每次总是写“Output from B”。有没有办法让它按照我想要的方式工作?

编辑修复代码示例。

I have 2 classes:

public class A
{
    public void WriteLine(string toWrite) { Console.WriteLine(toWrite); }
}

public class B : A
{
    public new void WriteLine(string toWrite) { Console.WriteLine(toWrite + " from B"); }
}

In my code I do the following:

B writeClass = new B();
writeClass.WriteLine("Output"); // I expect to see 'Output from B'
A otherClass = (A)writeClass;
otherClass.WriteLine("Output"); // I expect to see just 'Output'

I presumed this would work because of polymorphism.

However, it always writes 'Output from B' every time. Is there anyway to get this to work the way I want it to?

EDIT Fixing code example.

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

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

发布评论

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

评论(6

离笑几人歌 2024-12-07 11:29:21

当您使用 NEW 从基类“隐藏”方法时,您只是隐藏它,就是这样。当您显式调用基类实现时,它仍然会被调用。

A 不包含 WriteLine,因此您需要修复它。当我修复它时我得到了

Output from B
Output


namespace ConsoleApplication11
{
    class Program
    {
        static void Main(string[] args)
        {
            B writeClass = new B(); 
            writeClass.WriteLine("Output"); // I expect to see 'Output from B' 
            A otherClass = (A)writeClass; 
            otherClass.WriteLine("Output"); // I expect to see just 'Output' 
            Console.ReadKey();
        }
    }

    public class A
    {
        public void WriteLine(string toWrite) { Console.WriteLine(toWrite); }
    }
    public class B : A
    {
        public new void WriteLine(string toWrite) { Console.WriteLine(toWrite + " from B"); }
    }
}

When you "hide" a method from the base class using NEW you are just hiding it, thats it. It's still called when you explicitily call the base class implementation.

A doesnt contain WriteLine so you need to fix that. When I fixed it I got

Output from B
Output


namespace ConsoleApplication11
{
    class Program
    {
        static void Main(string[] args)
        {
            B writeClass = new B(); 
            writeClass.WriteLine("Output"); // I expect to see 'Output from B' 
            A otherClass = (A)writeClass; 
            otherClass.WriteLine("Output"); // I expect to see just 'Output' 
            Console.ReadKey();
        }
    }

    public class A
    {
        public void WriteLine(string toWrite) { Console.WriteLine(toWrite); }
    }
    public class B : A
    {
        public new void WriteLine(string toWrite) { Console.WriteLine(toWrite + " from B"); }
    }
}
孤云独去闲 2024-12-07 11:29:21

A 类的方法是 Write,而不是 WriteLine。将其更改为相同的名称,它将按您的预期工作。我刚刚尝试了一下并得到:

Output from B
Output

多态性(C# 编程指南)很好地解释了这一点。 (这是原始海报链接的较新版本。)该页面显示了派生类重写虚拟成员以及新成员隐藏基类成员的示例。

新的修饰符似乎存在一些混乱。来自文档

尽管您可以在不使用 new 修饰符的情况下隐藏成员,但是
结果是一个警告。如果您使用 new 显式隐藏成员,则会
抑制此警告并记录派生的事实
版本旨在作为替代品。

请注意,隐藏成员不必是虚拟的。

最佳实践:

  • 强烈倾向于覆盖而不是隐藏。多态调用是面向对象语言中的惯用法。
  • 如果您打算隐藏成员,请始终使用 new 修饰符。
  • 切勿发布带有编译器警告的代码。
  • 如果您团队中的每个开发人员都同意无法修复编译器警告,请禁止它。

Your method on class A is Write, not WriteLine. Change it to the same name and it will work as you expect. I just tried it and get:

Output from B
Output

Polymorphism (C# Programming Guide) explains this quite well. (This is the newer version of the original poster's link.) The page shows examples where a derived class overrides a virtual member and where new members hide base class members.

There appears to be some confusion over the new modifier. From the documentation:

Although you can hide members without the use of the new modifier, the
result is a warning. If you use new to explicitly hide a member, it
suppresses this warning and documents the fact that the derived
version is intended as a replacement.

Note that the hidden member does not need to be virtual.

Best practices:

  • Strongly prefer overriding to hiding. Polymorphic calls are idiomatic in OO languages.
  • If you intend to hide a member, always use the new modifier.
  • Never release code with compiler warnings.
  • If every developer on your team agrees that a compiler warning cannot be fixed, suppress it.
顾冷 2024-12-07 11:29:21

重写类 B 中的方法时,请勿使用 new 关键字。并将A中的方法声明为virtual

Don't use new keyword when you override the method in class B. And declare the method in A as virtual.

波浪屿的海角声 2024-12-07 11:29:21

'new' 关键字使 B 的 WriteLine 实现覆盖 A 的实现。

不要接受这个答案,但根据我的经验,以这种方式使用“new”关键字几乎总是错误的。代码的可读性较差,而且代码的清晰度也很混乱。

The 'new' keyword is making B's implementation of WriteLine overwrite A's implementation.

Don't accept this as an answer, but in my experience, it's almost always a mistake to use the 'new' keyword in this fashion. It's less readable and muddy's the clarity of your code.

沫离伤花 2024-12-07 11:29:21

你的类 A 有一个 Write 函数而不是 WriteLine

public class A
{
    public virtual void WriteLine(string toWrite) { Console.WriteLine(toWrite); }
}

public class B : A
{
    public override void WriteLine(string toWrite) { Console.WriteLine(toWrite + " from B"); }
}

Your class A has a Write function instead of WriteLine

public class A
{
    public virtual void WriteLine(string toWrite) { Console.WriteLine(toWrite); }
}

public class B : A
{
    public override void WriteLine(string toWrite) { Console.WriteLine(toWrite + " from B"); }
}
尹雨沫 2024-12-07 11:29:21

第一:我猜你想将这两个方法命名为“WriteLine”,但 A 类中的方法仅命名为“Write”。第二:是的,你从 A 继承了 B,但对象仍然是“B”类型,所以现在我认为你想要的不可能。

First: I guess you wanted to name the methods both "WriteLine" but the one in class A is only named "Write". And second: yes you inherit B from A but the object will still be of type "B" so now I don't think what you want is possible.

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