C#:理解事件语法
我需要一些帮助来了解如何创建新的自定义事件。我从 首先,我没有真正理解代表部分。在正常变量申报中C#:理解事件语法,c#,C#,我需要一些帮助来了解如何创建新的自定义事件。我从 首先,我没有真正理解代表部分。在正常变量申报中 protected string str1; 但这里我有额外的(ChangingHandler)。我如何理解这一点?我知道这有点像是用一个变形金刚来处理这件事,但这让我有点不舒服 public event ChangingHandler Change 然后 我真的不明白新汽车的语法 C#中的事件有点像方法指针的集合。它说:“大家好,如果你们关心我,给我一个指向我可以调用的方法的指针,我会抓住它,
protected string str1;
但这里我有额外的(ChangingHandler
)。我如何理解这一点?我知道这有点像是用一个变形金刚来处理这件事,但这让我有点不舒服
public event ChangingHandler Change
然后
我真的不明白新汽车的语法 C#中的事件有点像方法指针的集合。它说:“大家好,如果你们关心我,给我一个指向我可以调用的方法的指针,我会抓住它,当我想向全世界宣布发生了什么时,我会调用你们给我的所有方法。”
这样,有人可以给事件一个指向其方法的指针,称为“事件处理程序”。只要事件的所有者认为合适,事件就会调用此方法
从这个意义上讲,委托只不过是说明事件将接受哪种方法。你不能让一个人给事件一个不带参数的方法和一个带5参数的方法,它不知道如何调用它们。因此,委托是事件和事件处理程序之间的契约,告诉它们对方法签名的期望
在您的情况下,最好只使用EventHandler
,它是一个内置的委托,形式为void EventHandler(object sender,T eventArgs)
,用于您的事件委托,如下所示:
public event EventHandler<CarArgs> Change;
if (Change != null) // You wouldn't access an array without making sure it wasn't null, would you?
{
Change(this, new CarArgs()); // This executes every method body in it's array using the signature definition the delegate defined.
// The delegate simply exists so this code knows the method signature
// so it can know how to call those method body's for you.
}
您正在给事件一个新的委托(函数指针),该委托指向您的car\u Change事件处理程序,告诉事件在准备就绪时调用您的car\u Change方法。代理(
newchangehandler(…)
只是将指针包装到car\u Change方法。同样,事实证明您不需要car.Change+=new car.ChangingHandler(car\u Change);
sytax,因为它不像您指出的那样直观
您可以简单地编写
car.Change+=car\u Change;
假设car\u Change
具有正确的方法签名。事件具有特定的签名。此签名定义侦听器在参数和返回类型方面的外观。此契约通过定义委托来表示。从代码示例:
public delegate void ChangingHandler (object sender, CarArgs ca);
这里,我们定义了一个委托,用于将对象
和CarArgs
作为参数,并使用void
返回类型的方法
接下来,我们宣布该事件如下:
public event ChangingHandler Change;
因此,我们有一个名为Change
的事件,该事件的侦听器必须与ChangingHandler
委托具有相同的签名
然后我们需要一个侦听器方法:
private void car_Change(object sender, CarArgs ca) {
MessageBox.Show(ca.Message());
}
在这里,我们可以看到它如何与ChangingHandler
委托具有相同的签名
最后,我们可以将listner附加到事件:
car.Change+=new Car.ChangingHandler(car_Change)
因此,我们创建一个新的ChangingHandler
实例,该实例引用car\u Change
方法,并将委托实例传递给事件
综上所述,我建议使用预定义的EventHandler
委托,而不是创建自己的委托:
public event EventHandler<CarArgs> Change;
公共事件事件处理程序更改;
一种粗略的思考方式:委托类型定义了作为事件基础的“函数形状”。因此,ChangingHandler
是函数必须看起来的样子
更进一步说,委托实例就像一个函数指针
public event ChangingHandler Change
定义了一个名为Change
的函数指针,该指针将指向形状为ChangingHandler
的函数
但是目前,这个函数指针没有指向任何东西。这就是car.Change+=new car.ChangingHandler(car\u Change)
位的作用
分两步进行。委托不是普通的函数指针;它们实际上更像函数指针堆栈,可以将多个函数分配给委托。这就是为什么人们更常谈论“订阅”的原因将函数添加到事件将意味着在事件激发时将调用它。使用+=运算符将函数添加到委托“堆栈”中
你不能直接将函数添加到委托中,它是用委托本身来表示的。这是一种一次性的方式,在将函数添加到事件的同一行上创建一个新的对象;尽管从C#2.0开始,我相信你可以直接添加函数,而无需调用新的语法。nts基于委托的概念,委托基本上是一个方法签名定义。仅此而已。就像在接口中如何定义方法签名,但没有实现它们一样,在继承该接口的所有类中都是这样做的 委托是方法签名的定义,您可以为其定义任意多个方法体,例如,给定此委托(方法签名定义): 您可以使用此委托(方法签名定义)定义实体,如下所示: 不过,这是一种旧的定义委托的方式,现在使用lambdas而不是delegate关键字来创建方法体更具可读性,就像我所做的那样,但这对问题并不重要 现在,可以将事件想象为一个委托(方法签名定义),具有一系列主体,这些主体被称为订阅事件,将方法主体订阅到事件的语法是
+=
,还有从事件订阅中删除方法主体的语法是-=
因此,这里的代码为ChangingHandler委托定义了一个主体数组(方法签名定义):
您可以通过调用以下方法将主体(添加到数组)订阅到此分组:
public void SomeMethodWhichSubscribesADelegateBodyToAnEvent()
{
ChangingHandler myChangingHandler = new ChangingHandler(
delegate(object sender, EventArgs e) { /* the method body for myChangingHandler */ }
);
Change += myChangingHandler;
}
现在是除夕夜的全部原因
public event EventHandler<CarArgs> Change;
public delegate void ChangingHandler (object sender, CarArgs ca);
public void SomeMethodWhichCreatesADelegateBody()
{
ChangingHandler myChangingHandler = new ChangingHandler(
delegate(object sender, EventArgs e) { /* the method body for myChangingHandler */ }
);
}
public event ChangingHandler Change;
public void SomeMethodWhichSubscribesADelegateBodyToAnEvent()
{
ChangingHandler myChangingHandler = new ChangingHandler(
delegate(object sender, EventArgs e) { /* the method body for myChangingHandler */ }
);
Change += myChangingHandler;
}
if (Change != null) // You wouldn't access an array without making sure it wasn't null, would you?
{
Change(this, new CarArgs()); // This executes every method body in it's array using the signature definition the delegate defined.
// The delegate simply exists so this code knows the method signature
// so it can know how to call those method body's for you.
}