简单事件c#

时间:2012-12-14 13:52:48

标签: c# events exception

我有两个类,我必须创建一个事件来在这些类之间进行通信。

Class a
{
    public delegate void delegat(int a);
    public event delegat exit;
    ...
    private void a_FormClosed(object sender, FormClosedEventArgs e)
    {
         // My event named exit should run here, but I get exception!
        exit(100);
    }
}

Class b
{
    a instance=new a();
    a.exit+=new a.delegat(my_fun);
    ...
    private void my_fun(int x)
    {
        if(x==100)
        do_smth;
        ...
    }
}

但问题是我得到了异常:“对象引用未设置为对象的实例”。 我无法理解我做错了什么?我应该在哪里创建一个新的实例? 谢谢你的帮助!

4 个答案:

答案 0 :(得分:2)

您正尝试在本身而不是实例上分配exit事件,例如

a.exit += ...

应该是:

instance.exit += ...

在尝试触发之前,您还没有检查是否已分配了exit事件。还有其他一些问题,比如竞争条件,你没有考虑到这些问题。

以下是处理事件的相对安全的方式的一般示例,例如

public class A
{
    public delegate void ExitHandler(object sender, int a);
    public event ExitHandler Exit;
    ...
    private void a_FormClosed(object sender, FormClosedEventArgs e)
    {
        OnExit(100);
    }

    protected virtual void OnExit(int a)
    {
        // take a reference to the event (incase it changes)
        var handler = Exit;
        if (handler != null)
        {
            handler(this, a);
        }
    }

}

public class B
{
    private A _a;

    public B()
    {
        _a = new A();
        _a.Exit += (sender, value) => my_fun(value);
    }

    private void my_fun(int x)
    {
        if(x==100)
            do_smth;
        ...
    }
}

答案 1 :(得分:0)

在提升之前验证您的活动是否存在任何订阅者:

if (exit != null)
    exit(100);

另一个选项 - 在A类中定义事件时订阅虚拟事件处理程序:

public event delegat exit = (_) => { };

还对类型,事件和方法使用PascalCase命名。并且.NET中有预定义的委托,它接收一个参数并返回void:Action<T>

答案 2 :(得分:0)

我会改变&#34; a class&#34;调用事件的代码如下:

Class a
{
  public delegate void delegat(int a);
  public event delegat exit;
  ...
  private void a_FormClosed(object sender, FormClosedEventArgs e)
    {
     if (this.exit != null)  // just in case a_FormClosed fires before assigning the event
         exit(100);//here should run my event named exit but i get exception!
     }
}

答案 3 :(得分:0)

试试这个

namespace foo
    {
    public delegate void delegat(int a);
    Class a
    {
      public event delegat exit;
      private void a_FormClosed(object sender, FormClosedEventArgs e)
        {
if(exit != null)
{
         exit(100);//here should run my event named exit but i get exception!
    }
         }
     }
    }

     Class b
     {
      a instance=new a();
      instance.exit+=new delegat(my_fun);
      ...
      priavte void my_fun(int x)
      {
       if(x==100)
        do_smth;
       ...
       }
     }