注意:以下所有类都在同一名称空间中定义,并在同一文件中定义.
此类允许您使用一些提供的文本为写入控制台的任何内容添加前缀.
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初始化BaseClass.consoleWriter成员.
>使用BaseClass.consoleWriter变量调用并执行该方法
然后
> CLR调用NewClass.Write()
> CLR初始化NewClass.consoleWriter对象.
> CLR发现实现位于BaseClass中,但该方法是继承的
> CLR使用NewClass.consoleWriter变量在本地(在NewClass中)执行该方法
我认为这是继承结构的工作原理吗?
请有人帮我理解为什么这不起作用?
–
更新:
这种情况将如下工作(我如何实现它)
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.