Dom*_*icz 6 c# inheritance new-operator
我很困惑为什么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!
我不明白为什么会这样.以下是关于发生的事情的思考过程:
BaseClass.Write()方法BaseClass.consoleWriter成员.BaseClass.consoleWriter变量调用并执行该方法然后
NewClass.Write()NewClass.consoleWriter对象.BaseClass,但该方法是继承的NewClass使用NewClass.consoleWriter变量在本地(in )执行方法我认为这是继承结构的工作原理吗?
请有人帮我理解为什么这不起作用?
-
更新:
这种情况将如下工作(我如何实现它)
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;
         }
    }
}
...
该new运营商实际上并没有覆盖多态性的感觉.它只是添加了另一种"发生"的方法,它具有相同的签名,但却被视为一种单独的方法.只有在子类上显式执行该方法时,才会使用"新"实现.
在您的情况下,您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);
    }
}
...或者,你最想要的是什么,而是通过使用而不是在多态性的意义上引入真正的重写.但是,您的基类需要通过声明consoleWriter来支持它.此外(正如您在评论中提到的),只有在您不将这些方法设为静态时,此方法才有效.overridenewvirtual
如果您仍想要对记录器进行静态访问,或者查看已经为您解决了所有这些问题的log4net,则可以应用Singleton模式.