引发自定义事件时出错

时间:2016-12-15 12:50:55

标签: c# events delegates custom-events

我有一个会写日志的课程。该课程需要提出一个事件(在下面未指出的特定情况下),这个事件将由一个类来对其作出反应。我有下面的代码,但是一旦我尝试举起活动,我就会在指示的行上收到错误,

  

对象引用未设置为对象的实例

知道我错过了什么吗?

//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)
   { ... }
}

1 个答案:

答案 0 :(得分:0)

两个问题:

  • 无论是否有人订阅,您都会举起活动。不要这样做 - 如果NullReferenceException为空时拨打WriteLog(this, e)获得WriteLog。在C#6中,很容易避免这种情况:

    WriteLog?.Invoke(this, e);
    
  • 您在与提升事件的实例不同的LogEvent实例上订阅该事件。这是一个设计问题而不是其他任何问题 - 单个日志事件有一个订阅者列表是没有意义的。相反,您应该拥有Logger或类似的订阅者(通过事件),然后将每个LogEvent传递给这些订阅者。您创建一个 Logger,订阅它,然后在同一个实例上调用WriteLog