2

我有两个班级,我必须制作一个事件来在这些班级之间进行交流。

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

4 回答 4

2

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

a.exit += ...

应该:

instance.exit += ...

You also aren't checking whether your exit event has been assigned before attempting to fire it. There are other issues which you haven't taken into consideration like race conditions.

Here is a general example of a relatively safe way of handling events e.g.

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;
        ...
    }
}
于 2012-12-14T14:01:50.827 回答
0

在引发之前验证您的事件是否存在订阅者:

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

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

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

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

于 2012-12-14T13:59:11.737 回答
0

I would change "class a" code for calling the event to as follows:

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!
     }
}
于 2012-12-14T14:02:38.273 回答
0

Try this

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;
       ...
       }
     }
于 2012-12-14T14:07:19.600 回答