【问题标题】:C# Class Changed Event causing Object reference not set to an instance of an objectC# 类更改事件导致对象引用未设置为对象的实例
【发布时间】:2011-06-02 18:23:14
【问题描述】:

我需要在更改属性时触发一个事件。当我运行此代码时,我得到一个未设置为对象实例的对象引用。我究竟做错了什么?实例化事件并在设置属性时触发它的正确方法是什么?

公共成员:

public event System.EventHandler ClassChanged;

属性集:

ClassChanged(this, EventArgs.Empty);

【问题讨论】:

    标签: c# events


    【解决方案1】:

    您需要先验证事件处理程序不为空:

    if (ClassChanged != null)
        ClassChanged(this, EventArgs.Empty);
    

    但一般来说,您可能希望将其包装成一个辅助方法,如下所示:

    private void NotifyClassChanged() {
        if (ClassChanged != null)
            ClassChanged(this, EventArgs.Empty);
    }
    

    或者可能实现INotifyPropertyChanged

    【讨论】:

    • +1(如果我今天还有票)为 INotifyPropertyChanged 位。您的通灵调试将其提升到了一个新的水平!
    • 我同意 - INotifyPropertyChanged 听起来像是这里的合适选项。话虽如此,我更喜欢在空检查之前制作调用列表的副本(为了线程安全)——即使它是单线程的,也是一个好习惯。
    • ClassChanged 不为空,我仍然抛出相同的异常
    • @Kevin - 问题可能出在其他地方。 Visual Studio 没有显示异常发生的位置吗?
    • @Kevin:我们可以得到堆栈跟踪吗?也许处理程序本身有一个NullReferenceException
    【解决方案2】:

    试试这个:

    System.EventHandler handler = this.ClassChanged;
    if (handler != null)
    {
        handler(this, EventArgs.Empty);
    }
    

    【讨论】:

      【解决方案3】:

      这样做是因为没有事件处理程序已订阅该事件。

      确保事件的多播委托不是线程安全的null 的正确方法:

      var cc = ClassChanged; //makes a copy
      if (cc != null)
          cc(this, EventArgs.Empty);
      

      但是,我更喜欢的方法是使用空的 lambda 处理程序声明事件,因此它永远不会是 null

      public event EventHandler ClassChanged = (o,e) => {};
      

      【讨论】:

      • 正如您所声明的public,什么是阻止某人设置:ClassChanged = null?为了安全起见,最好为竞争条件添加 null 检查。
      • @Matthew:在课堂之外,您只能使用+= 添加处理程序并使用-= 删除处理程序。 event 声明是带有支持委托的 AddHandlerRemoveHandler(而不是 getset)属性的语法糖。
      【解决方案4】:

      就像 joel 说的那样,这个方法没有附加列表,这就是你得到异常的原因。另一种处理方法是创建一个方法,该方法检查其是否为 null,然后调用此方法而不是 Event

      如果你有

      public event System.EventHandler ClassChanged;    
      
      ClassChanged(this, EventArgs.Empty);
      

      您创建以下方法

      private void OnClassChanged()
      {
         if (ClassChanged != null)
         {
             ClassChanged(this, EventArgs.Empty);
         }
      }
      

      并调用 OnClassChanged(...) 而不是 ClassChanged(...) 事件

      【讨论】:

        【解决方案5】:

        可能是没有附加到 ClassChanged 的​​事件处理程序。 (看不到其余代码) 因此,在触发之前先检查 ClassChanged 是否不为空。

        if (ClassChanged != null)
        {
          ClassChanged(this, nully);
        
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-09-09
          • 1970-01-01
          • 1970-01-01
          • 2013-10-13
          • 2012-07-06
          • 1970-01-01
          • 2016-06-10
          • 1970-01-01
          相关资源
          最近更新 更多