C#:理解事件语法

Jie*_*eng 6 c#

我需要一些帮助,了解如何创建一个新的自定义事件.我从这里读到......

public delegate void ChangingHandler (object sender, CarArgs ca); 
public event ChangingHandler Change; 
...
private void car_Change(object sender, CarArgs ca) {
    MessageBox.Show(ca.Message());
} 
...
car.Change+=new Car.ChangingHandler(car_Change); // add event handler
...
Change(this,ca); // call event
Run Code Online (Sandbox Code Playgroud)

1,我真的没有得到代表的一部分.在正常的变量声明中,

protected string str1;
Run Code Online (Sandbox Code Playgroud)

但在这里我有额外的(ChangingHandler).我怎么理解这个?我知道像ChangingHandler这样的东西会被用来处理这个事件,但它会让我失望.

public event ChangingHandler Change
Run Code Online (Sandbox Code Playgroud)

然后

car.Change+=new Car.ChangingHandler(car_Change)
Run Code Online (Sandbox Code Playgroud)

我真的不懂语法new Car.ChangingHandler(car_Change).

Mat*_*eer 17

C#中的事件有点像方法指针的集合.它说"嘿大家,如果你关心我,给我一个指向我可以调用的方法的指针,我会坚持下去,当我想向世界宣布什么是什么时,我会调用所有的方法你给我."

这样,有人可以给事件指向他们的方法,这被称为"事件处理程序".只要事件所有者认为合适,事件就会调用此方法.

从这个意义上说,代表只不过是说这个事件会接受什么样的方法.你不能让一个人给这个事件一个不带参数的方法,一个拿5个的方法,它不知道如何调用它们.因此委托是事件和事件处理程序之间的契约,告诉他们对方法签名的期望.

在您的情况下,最好只使用EventHandler<T>,这是void EventHandler<T>(object sender, T eventArgs)您的事件委托的表单的内置委托,如下所示:

public event EventHandler<CarArgs> Change;
Run Code Online (Sandbox Code Playgroud)

C#实际上没有原始意义上的函数指针.代表们处理这个问题.它们就像强类型,面向对象的函数指针.你打电话的时候

car.Change+=new Car.ChangingHandler(car_Change);
Run Code Online (Sandbox Code Playgroud)

您正在为事件提供一个新的委托(函数指针),该委托指向您的car_Change事件处理程序,告诉事件在准备好时调用您的car_Change方法.委托(new ChangeHandler(...)简单地将指针包装到car_Change方法.


Fre*_*örk 11

一个事件有一定的签名.此签名定义了侦听器在哪些参数和应该具有的返回类型方面必须具有的外观.该合同通过定义代表来表达.从您的代码示例:

public delegate void ChangingHandler (object sender, CarArgs ca);
Run Code Online (Sandbox Code Playgroud)

在这里,我们为使用a object和a CarArgs作为参数以及void返回类型的方法定义了一个委托.

接下来我们将事件声明为:

public event ChangingHandler Change;
Run Code Online (Sandbox Code Playgroud)

因此,我们有一个名为的事件Change,并且事件的侦听器必须具有与ChangingHandler委托相同的签名.

然后我们需要一个监听器方法:

private void car_Change(object sender, CarArgs ca) {
    MessageBox.Show(ca.Message());
} 
Run Code Online (Sandbox Code Playgroud)

在这里,我们可以看到它与ChangingHandler委托具有相同的签名.

最后,我们可以将列表器附加到事件中:

car.Change+=new Car.ChangingHandler(car_Change)
Run Code Online (Sandbox Code Playgroud)

因此,我们创建一个ChangingHandler引用该car_Change方法的新实例,并将委托实例传递给该事件.

总而言之,我建议使用预定义的EventHandler<T>委托而不是创建自己的委托:

public event EventHandler<CarArgs> Change;
Run Code Online (Sandbox Code Playgroud)