简单事件c#
我有两个类,我必须制作一个事件来在这些类之间进行通信简单事件c#,c#,events,exception,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
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;
...
}
}
但问题是我得到了一个异常:“对象引用未设置为对象的实例”。
我不明白我做错了什么?我应该在哪里做一个新的例子?
谢谢你的帮助 在引发事件之前,请验证是否存在任何订阅服务器:
if (exit != null)
exit(100);
另一个选项-在类A中定义事件时订阅虚拟事件处理程序:
public event delegat exit = (_) => { };
对类型、事件和方法也使用PascalCase命名。NET中有一个预定义的委托,它接收一个参数并返回void:
Action
您试图在类本身而不是实例上分配exit
事件,例如
应该是:
instance.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;
...
}
}
我将调用事件的“class a”代码更改为:
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!
}
}
试试这个
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;
...
}
}
如何运行此代码?您是否创建了b的实例?您确定异常来自于与b中相同的a实例吗?您最大的问题是您在类上调用非静态方法。您创建了一个名为“instance”的实例,但从不使用它,因为您直接在a上调用所有内容。改为在“实例”上调用它们,看看会发生什么。当我按下“b”窗体上的某个按钮时,会生成“a”类的实例。然后,.ShowDialog()函数显示“a”类窗体,我在“a”窗体上执行一些操作。正如您所看到的,我的事件应该在其他事件触发时触发(“a”窗体上的formClosed事件)。可能有什么问题吗?是的,我确信异常来自以下部分:private void a_FormClosed(object sender,FormClosedEventArgs e){exit(100);//这里应该运行名为exit的事件,但我得到异常!}
Hoeloe-我发现了这些错误:我应该这样写smth:instance.exit+=newa.delegat(我的乐趣)
而不是a.exit+=new a.delegat(我的乐趣)代码>但它仍然抛出一个异常。+1,但我还建议对事件参数(从EventArgs
继承的对象)使用约定@ken2k这可能更像是一个首选项,我更喜欢EventArgs
,而不是委托自己。但是,使用委托没有问题。最佳做法还包括为事件/委托约定引发事件的受保护的方法。另一件重要的事情是事件处理程序的对象发送者
第一个参数。@lazyberezovsky是的,但是,没有提到类作为基类公开,甚至没有提到它被继承。我通常以“实现我需要的”的方式进行开发,而不是“实现我可能需要的”-但是,作为参考,我已经更新了签名,因为无论哪种方式,它都不会影响OP尝试执行的操作:)我还更新了代理以传递发件人(good point@ken2k)
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;
...
}
}