我有一个记录器API,可用于记录文本。 记录器有一些属性,我可以用来记录envent类型(Info,Err等...),源app(app1,app2等等)和mesg文本。
语法很简单,工作正常:
Logger log = new Logger();
log.Write("Information", "SourceApplication", "Test text to log");
现在我想创建2个静态类,一个用于"通用日志记录"和其他用于"调试记录"。目标是避免为每个模块利用率创建记录器对象的新实例。每个类都应该能够在没有实例化的情况下使用这些对象(静态类应该自动处理)。
"调试记录" - 可以由解决方案内的任何项目使用,并且应该是单例。 要使用的来电码应为:
LoggerDebug.Write("Debug", "Debugger", "Test text to log");
通用日志记录 - 供所有项目模块使用但在每次使用后,静态类应该处理Logger对象 要使用的来电码应为:
LoggerDebug.Write("Information", "App1", "Test text to log");
我试着从" Debug Logging"开始静态类,我读(http://csharpindepth.com/Articles/General/Singleton.aspx),但我不确定这是否是正确的方法... 你能给我一些建议吗?
using System;
using System.Diagnostics;
using System.Collections.Generic;
namespace Common
{
public sealed class LoggerDebug
{
private static LoggerDebug instance = null;
private static readonly object padlock = new object();
private static Logger log;
static LoggerDebug Instance
{
get
{
lock (padlock)
{
if (instance == null)
{
instance = new LoggerDebug();
}
return instance;
}
}
}
public LoggerDebug()
{
log = new Logger();
}
public static void Write(String EventType, string appSource, string text)
{
log.Write(EventType, appSource, string.Format("Test {0}", text));
}
}
}
来电者代码如下所示:
LoggerDebug.Write("Information", "App1", "Test text to log");
当我尝试运行应用程序时,它会崩溃:
未处理的类型' System.NullReferenceException' 发生在Common.dll中附加信息:对象引用不是 设置为对象的实例。
那说ctor没有实例化log = new Logger();
所以我可以用以下方法解决这个问题:
private static Logger log = new Logger();
评论ctor代码
public LoggerDebug()
{
//log = new Logger();
}
但我很困惑,不确定这是否是正确的方法,如何正确地做到这一点?
我可以使用的任何例子吗?
答案 0 :(得分:1)
这是更新的代码。由于没有实例成员/方法,因此将整个事物设置为静态。请参阅代码中的注释。
另一方面,我强烈建议您不要为学习经历以外的任何事情做这件事。使用Log4Net或NLog等现有框架,这些框架具有高度可配置性并经过广泛测试。
using System;
using System.Diagnostics;
using System.Collections.Generic;
namespace Common
{
// changed sealed to static as there are no instances
public static class LoggerDebug
{
// removed lock object
private static Logger log;
// added static constructor
static LoggerDebug(){
log = new Logger();
}
// no need for lock due to static constructor
// removed Instance
// removed instance constructor
public static void Write(String EventType, string appSource, string text)
{
log.Write(EventType, appSource, string.Format("Test {0}", text));
}
}
}
或者,您可以使用Singleton模式,但至少需要一个实例级别(非静态)成员才能使用它。
using System;
using System.Diagnostics;
using System.Collections.Generic;
namespace Common
{
// changed sealed to static as there are no instances
public sealed class LoggerDebug
{
// removed lock object
private static Logger log;
// added static constructor
static LoggerDebug(){
log = new Logger();
_logger = new LoggerDebug();
}
// singleton that is created only once
private static LoggerDebug _logger;
public static LoggerDebug Logger{
get{return _logger;}
}
// removed static keyword
public void Write(String EventType, string appSource, string text)
{
log.Write(EventType, appSource, string.Format("Test {0}", text));
}
}
}
您也可以像在示例中一样初始化静态字段。理想情况下,您永远不会想要在实例级别成员中初始化静态字段,因为可能存在竞争条件以及必须编写为每个实例执行的检查的费用,这样做效率很低并且会导致代码变弱。