I am confused as to why the new
operator isn't working as I expected it to.
Note: All classes below are defined in the same namespace, and in the same file.
This class allows you to prefix any content written to the console with some provided text.
public class ConsoleWriter
{
private string prefix;
public ConsoleWriter(string prefix)
{
this.prefix = prefix;
}
public void Write(string text)
{
Console.WriteLine(String.Concat(prefix,text));
}
}
Here is a base class:
public class BaseClass
{
protected static ConsoleWriter consoleWriter = new ConsoleWriter("");
public static void Write(string text)
{
consoleWriter.Write(text);
}
}
Here is an implemented class:
public class NewClass : BaseClass
{
protected new static ConsoleWriter consoleWriter = new ConsoleWriter("> ");
}
Now here's the code to execute this:
class Program
{
static void Main(string[] args)
{
BaseClass.Write("Hello World!");
NewClass.Write("Hello World!");
Console.Read();
}
}
So I would expect the output to be
Hello World!
> Hello World!
But the output is
Hello World!
Hello World!
I do not understand why this is happening. Here is my thought process as to what is happening:
- The CLR calls the
BaseClass.Write()
method - The CLR initialises the
BaseClass.consoleWriter
member. - The method is called and executed with the
BaseClass.consoleWriter
variable
Then
- The CLR calls the
NewClass.Write()
- The CLR initialises the
NewClass.consoleWriter
object. - The CLR sees that the implementation lies in
BaseClass
, but the method is inherited through - The CLR executes the method locally (in
NewClass
) using theNewClass.consoleWriter
variable
I thought this is how the inheritance structure works?
Please can someone help me understand why this is not working?
--
Update :
This scenario would work as follows (how I've implemented it)
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");
}
The reason being I don't have to duplicate the code for every single class.
--
Update (after solution chosen):
So in order to get around this problem, instead of using base classes, I defined the functionality one. Then created new classes, which held Singleton instances for each layer:
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;
}
}
}
...