我有两个类,我必须创建一个事件来在这些类之间进行通信。
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;
...
}
}
但问题是我得到了异常:“对象引用未设置为对象的实例”。 我无法理解我做错了什么?我应该在哪里创建一个新的实例? 谢谢你的帮助!
答案 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;
...
}
}