我有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输出'。反正有没有让我按照我想要的方式工作?
编辑修复代码示例。
答案 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来显式隐藏成员,那么 抑制此警告并记录派生的事实 版本旨在替代。
请注意,隐藏成员不需要是虚拟成员。
最佳做法:
答案 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”类型,所以现在我不认为你想要的是什么。