2011-08-17 55 views
2

我从Effective C#项目23获得下面的代码应打印一个基类派生的:MyDerivedMessage从实现的接口

namespace ConsoleApplication1 
{ 

    interface IMsg 
    { 
     void message(); 
    } 

    public class MyMessage : IMsg 
    { 
     public void message() 
     { 
      Console.WriteLine("MyMessage"); 
     } 
    } 

    public class MyDerivedMessage : MyMessage 
    { 
     public new void message() 
     { 
      Console.WriteLine("MyDerivedMessage"); 
     } 
    } 

    class Test 
    { 

     static void Main() 
     { 
      MyDerivedMessage mdm = new MyDerivedMessage(); 
      IMsg im = mdm as IMsg; 
      im.message(); 
     } 
    } 
} 

书:

public class MyDerivedClass : MyClass 
{ 
    public new void Message() 
    { 
     Console.WriteLine("MyDerivedClass"); 
    } 
} 

添加的IMSG关键字的改变您派生的 类的行为,以便IMsg.Message()现在使用派生类版本:

MyDerivedClass d = new MyDerivedClass(); 
d.Message(); // prints "MyDerivedClass". 
IMsg m = d as IMsg; 
m.Message(); // prints " MyDerivedClass " 

为什么我仍然可以MyMessage印刷我加上“新”来MyDerivedMessage::message()后?

回答

3

你是隐藏(或遮蔽)的方法,而不是覆盖它。这意味着当您从声明为该类(或更多派生类)的变量访问派生类时,您只会调用该方法。

注意,这是在非虚方法的默认,所以加入“新”只是被更加明确。

如果不希望这种行为,你需要做的message方法在基类的虚,并在派生类中重写它。

又见看起来也许这本书有一些勘误表上new Modifier

+0

呀第二部分与虚拟和覆盖香港专业教育学院做了,但我搞不清为什么书上说,它将打印派生消息。 – Kobe

+0

我不熟悉的书,但只有两个选项:1)有书中错误,或2)你误解了该书的那个部分。如果您使用与本书中相同的代码,并声称输出应该不同,那么这本书就有错误。 –

+0

是的,这本书有一个错误 - 检查这里有效的C#的勘误表:http://billwagner.cloudapp.net/EffectiveCSharp它涉及您正在阅读的部分。 –

1

的文件,但你的MyDerivedMessage类还需要实现IMSG。如果没有发生这种情况,那么当因为在Interface和MyDerivedMessage之间创建的链而调用im.message()时,转换为IMsg只会将MyMessage看作具有Message()方法。

MyDerivedMessage是,一个MyMessage MyMessage是,一个IMSG MyDerivedMessage不是is-a的IMSG

public class MyDerivedMessage : MyMessage, IMsg 
{ 
    public new void message() 
    { 
     Console.WriteLine("MyDerivedMessage"); 
    } 
}