C# - 基类中的调用方法

时间:2011-08-18 22:37:32

标签: c# .net inheritance .net-4.0 polymorphism

我有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'

我认为这会因polymorphism.

而起作用

但是,它总是每次写入'B输出'。反正有没有让我按照我想要的方式工作?

编辑修复代码示例。

6 个答案:

答案 0 :(得分:5)

当你使用NEW从基类“隐藏”一个方法时,你只是隐藏它,就是这样。当你明确地调用基类实现时,它仍然被调用。

不包含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"); }
    }
}

答案 1 :(得分:1)

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

Output from B
Output

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

新修饰符似乎有些混乱。来自documentation

  

虽然你可以在不使用new修饰符的情况下隐藏成员,但是   结果是一个警告。如果您使用new来显式隐藏成员,那么   抑制此警告并记录派生的事实   版本旨在替代。

请注意,隐藏成员不需要是虚拟成员。

最佳做法:

  • 非常喜欢覆盖隐藏。多态调用在OO语言中是惯用的。
  • 如果您打算隐藏成员,始终使用新修饰符。
  • 永远不要发布包含编译器警告的代码。
  • 如果团队中的每个开发人员都同意无法修复编译器警告,请将其取消。

答案 2 :(得分:0)

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

答案 3 :(得分:0)

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

不要接受这个作为答案,但根据我的经验,以这种方式使用'new'关键字几乎总是错误的。它的可读性和泥泞程度都低于代码的清晰度。

答案 4 :(得分:0)

你的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"); }
}

答案 5 :(得分:0)

首先:我想你想把这些方法命名为“WriteLine”,但是A类中的方法只是命名为“Write”。第二个:是的,你从A继承B但是对象仍然是“B”类型,所以现在我不认为你想要的是什么。