C#中的new运算符不会覆盖基类成员
我很困惑为什么新的运算符不能像我预期的那样工作.
注意:以下所有类都在同一名称空间中定义,并在同一文件中定义. 此类允许您使用一些提供的文本为写入控制台的任何内容添加前缀. public class ConsoleWriter { private string prefix; public ConsoleWriter(string prefix) { this.prefix = prefix; } public void Write(string text) { Console.WriteLine(String.Concat(prefix,text)); } } 这是一个基类: public class BaseClass { protected static ConsoleWriter consoleWriter = new ConsoleWriter(""); public static void Write(string text) { consoleWriter.Write(text); } } 这是一个实现的类: public class NewClass : BaseClass { protected new static ConsoleWriter consoleWriter = new ConsoleWriter("> "); } 现在这是执行此操作的代码: class Program { static void Main(string[] args) { BaseClass.Write("Hello World!"); NewClass.Write("Hello World!"); Console.Read(); } } 所以我希望输出是 Hello World! > Hello World! 但输出是 Hello World! Hello World! 我不明白为什么会这样.以下是关于发生的事情的思考过程: > CLR调用BaseClass.Write()方法 然后 > CLR调用NewClass.Write() 我认为这是继承结构的工作原理吗? 请有人帮我理解为什么这不起作用? – 更新: 这种情况将如下工作(我如何实现它) public class LogBase { protected static TraceSource logger = new TraceSource(""); public static void Error (string text) { logger.WriteError(text); } public static void Info (string text) { logger.WriteInformation(text); } public static void Warning (string text) { logger.WriteWarning(text); } public static void Verbose (string text) { logger.WriteVerbose(text); } } // DataAccess logging public class DALog : LogBase { protected new static TraceSource logger = new TraceSource("DataAccess"); } // BusinessObjects logging public class BOLog : LogBase { protected new static TraceSource logger = new TraceSource("Objects"); } // BusinessLogic logging public class BLLog : LogBase { protected new static TraceSource logger = new TraceSource("Logic"); } // WebUI logging public class WebUILog : LogBase { protected new static TraceSource logger = new TraceSource("WebUI"); } 原因是我不必为每个类复制代码. – 更新(选择解决方案后): 因此,为了解决这个问题,我没有使用基类,而是定义了一个功能.然后创建新类,为每个层保存Singleton实例: public sealed class LogBase { private TraceSource logger = null; public static LogBase GetLogger(string loggerName) { return new LogBase(loggerName); } private LogBase(string loggerName) { logger = new TraceSource(loggerName); } public void Error (string text) { logger.WriteError(text); } public void Info (string text) { logger.WriteInformation(text); } public void Warning (string text) { logger.WriteWarning(text); } public void Verbose (string text) { logger.WriteVerbose(text); } } // DataAccess logging - no base class public class DALog { private static LogBase logger; public static LogBase Instance { get { if (logger==null) { logger = new TraceSource("DataAccess"); } return logger; } } } ... 解决方法
新的运算符实际上并没有在多态性的意义上覆盖.它只是添加了另一种“发生”的方法,它具有相同的签名,但却被视为一种单独的方法.只有在子类上显式执行该方法时,才会使用“新”实现.
在您的情况下,您已在基类上实现了Write.在那里,你有调用consoleWriter的行.该行引用基类,因此使用原始实现.它甚至不知道子类中的附加实现. 检查您的代码并将其视为原样: public class BaseClass { protected static ConsoleWriter consoleWriter = new ConsoleWriter(""); public static void Write(string text) { consoleWriter.Write(text); } } public class NewClass : BaseClass { protected static ConsoleWriter anotherConsoleWriter = new ConsoleWriter(">"); } 你的BaseClass.Write不会考虑调用anotherConsoleWriter而不是consoleWriter. 如果您希望您的示例有效,您需要为Write添加一个新实现: public class NewClass : BaseClass { protected new static ConsoleWriter consoleWriter = new ConsoleWriter(">"); public static new void Write(string text) { consoleWriter.Write(text); } } …或者,你最想要的东西,而是通过使用override而不是new来引入多态性意义上的真正覆盖.但是,您的基类需要通过将consoleWriter声明为虚拟来支持它.此外(正如您在评论中提到的),只有在您不将这些方法设为静态时,此方法才有效. 如果您仍希望静态访问记录器,则可以应用Singleton pattern,或者查看已经为您解决所有这些问题的log4net. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |