我有一个会写日志的课程。该课程需要提出一个事件(在下面未指出的特定情况下),这个事件将由一个类来对其作出反应。我有下面的代码,但是一旦我尝试举起活动,我就会在指示的行上收到错误,
对象引用未设置为对象的实例
知道我错过了什么吗?
//1. Class where event is registered
public class LogEvent
{
public delegate void WriteLogEventHandler(object Sender, WriteLogEventArgs e);
public event WriteLogEventHandler WriteLog;
public class WriteLogEventArgs : EventArgs
{
public string Message { get; set; }
public WriteLogEventArgs(string message) : base()
{
Message = message;
}
}
//Raise the event.
internal void OnWriteLog(WriteLogEventArgs e)
{
WriteLog(this, e); //Error here. Seems like WriteLog is null
}
//2. Class where event is raised.
public class Logs
{
public static void WriteLog(string message)
{
LogEvent.WriteLogEventArgs args = new LogEvent.WriteLogEventArgs(message);
new LogEvent().OnWriteLog(args);
}
}
//3. Class where event should be consumed
public class MyClass()
{
private LogEvent _logEvent;
public MyClass()
{
//Subscribe to event:
_logEvent = new LogEvent();
_logEvent.WriteLog += (sender, args) => { DoSomething(args.Message); };
}
public void DoSomething(string message)
{ ... }
}
答案 0 :(得分:0)
两个问题:
无论是否有人订阅,您都会举起活动。不要这样做 - 如果NullReferenceException
为空时拨打WriteLog(this, e)
,将获得WriteLog
。在C#6中,很容易避免这种情况:
WriteLog?.Invoke(this, e);
您在与提升事件的实例不同的LogEvent
实例上订阅该事件。这是一个设计问题而不是其他任何问题 - 单个日志事件有一个订阅者列表是没有意义的。相反,您应该拥有Logger
或类似的订阅者(通过事件),然后将每个LogEvent
传递给这些订阅者。您创建一个 Logger
,订阅它,然后在同一个实例上调用WriteLog
。