[英]EventHandler<T> and EventHandler
I want to ask the different between EventHandler
and EventHandler<T>
. 我想问一下
EventHandler
和EventHandler<T>
之间的区别。
Previously I have implemented a EventHandler
, with a custom EventArgs which can be passed to the parent page from the user control. 以前,我实现了一个
EventHandler
,它带有一个自定义EventArgs,可以将其从用户控件传递到父页面。
I thought I need to apply EventHandler< T >
, however it can be implemented by using EventHandler
. 我以为我需要应用
EventHandler< T >
,但是可以通过使用EventHandler
来实现。 (in fact there is weird error when I trying to apply EventHandler<T>
, the program is worked but error is shown in the IDE which I couldn't solve [ C# Custom EventHandler ]) (实际上,当我尝试应用
EventHandler<T>
,出现了奇怪的错误,该程序可以运行,但是在IDE中显示了我无法解决的错误[ C#Custom EventHandler ])
Thus, I want to know in what situation I need to apply EventHandler < T >
? 因此,我想知道在什么情况下需要应用
EventHandler < T >
?
public event EventHandler AppendProcess;
public event EventHandler<MyEventArg> AppendProcess;
---Update--- this is how I invoke the event in the user control (as i said, i can pass object to parent page by doing this (although i don't know if it is correct to do so) ---更新---这就是我在用户控件中调用事件的方式(正如我所说,我可以通过这样做将对象传递给父页面(尽管我不知道这样做是否正确)
if (AppendProcess == null) { }
else
AppendProcess(this, new Common.WinLose_ProgressStage(Common.WinLose_SP_Parameter.upper, displayLevel + 1,
(int)Common.WinLose_Level.lvChild4, thename, refundratio,
selfproportion, -1, -1, loadlevel, isPlayer, betsource, gamecategory, false));
EventHandler<T>
is just a generic EventHandler
type, which avoids you having to declare a new delegate type for each kind of EventArgs
you want to use. EventHandler<T>
只是一个通用的EventHandler
类型,避免了您必须为每种要使用的EventArgs
声明新的委托类型。
Consider Control.KeyPress
for example. 以
Control.KeyPress
为例。 It's declared as an event of type KeyPressEventHandler
. 声明为
KeyPressEventHandler
类型的事件。 That delegate is just declared as: 该委托仅声明为:
public delegate void KeyPressEventHandler(object sender, KeyPressEventArgs e)
If EventHandler<T>
(and generics) had been around when that was created, the event could have been declared as an EventHandler<KeyPressEventArgs>
instead, saving a delegate declaration. 如果
EventHandler<T>
(和泛型)在创建时就已存在,则可以将事件声明为EventHandler<KeyPressEventArgs>
而保存委托声明。 There are many, many delegates which are just like EventHandler
, and only vary in the type of the second parameter - EventHandler<T>
avoids that redundancy. 就像
EventHandler
一样,有很多代表,并且只有第二个参数的类型有所不同EventHandler<T>
避免了这种冗余。
No if you don't have your own custom EventArgs
subclass, there's no reason to use EventHandler<T>
... but if you do, it's much better to use it, so that the method handling the event receives your custom EventArgs
subclass in a strongly-typed way. 不,如果你没有自己的自定义
EventArgs
子类,没有理由使用EventHandler<T>
...但如果你这样做,这是更好的使用它,从而使处理事件的方法接收定制EventArgs
的子类一种强类型的方式。
As an aside, your way of invoking the event handler isn't thread-safe. 顺便说一句,调用事件处理程序的方式不是线程安全的。 Another thread could unsubscribe the final event handler after your nullity check.
无效检查后,另一个线程可以取消订阅最终事件处理程序。 If you're using C# 5, you should write it as:
如果您使用的是C#5,则应将其编写为:
var handler = AppendProcess;
if (handler != null)
{
handler(this, new Common.WinLose_ProgressStage(...));
}
If you're using C# 6 or later, you can use the null conditional operator: 如果您使用的是C#6或更高版本,则可以使用null条件运算符:
// If AppendProcess is null, the arguments won't even be evaluated
AppendProcess?.Invoke(this, new Common.WinLose_ProgressStage(...));
EventHandler<T>
is the generic variant of EventHandler
. EventHandler<T>
是EventHandler
的通用变体。 Usually, you would override EventArgs
and EventHandler
to come up with an own event type. 通常,您将覆盖
EventArgs
和EventHandler
来提供自己的事件类型。 You still need to derive EventArgs
if you want to pass in custom properties to the e
argument, but you don't need to create a custom delegate for EventHandler
any more. 如果要将自定义属性传递给
e
参数,则仍需要派生EventArgs
,但不再需要为EventHandler
创建自定义委托。 You now can just say: 您现在可以说:
public event EventHandler<SomeEventArgs> SomeEvent;
Which is more convenient than: 哪个比:
public delegate void SomeEventHandler(object sender, SomeEventArgs e);
public event SomeEventHandler SomeEvent;
When your delegate signature doesn't change, EventHandler<T>
is much more straightforward to use. 当您的委托人签名不变时,
EventHandler<T>
更加易于使用。
From your other question: 从您的另一个问题:
Common.WinLose_ProgressStage wps = (Common.WinLose_ProgressStage)e;
That's a cast that could potentially fail, depending on how the method is invoked. 根据方法的调用方式,转换可能会失败。 There is nothing guaranteeing that your event handler only gets called with
Common.WinLose_ProgressStage
that can be inspected without checking your full program. 无法保证仅使用
Common.WinLose_ProgressStage
调用事件处理程序,而无需检查完整程序即可对其进行检查。 It could be called with a plain EventArgs
too: you made that possible by making the parameter type EventArgs
. 也可以使用简单的
EventArgs
来调用它:通过使参数类型EventArgs
成为可能。
EventHandler<T>
causes more compile-time type checking. EventHandler<T>
导致更多的编译时类型检查。 If other code attempts to pass in EventArgs.Empty
, the call would simply fail to compile. 如果其他代码尝试传递
EventArgs.Empty
,则该调用将仅无法编译。
It's basically the same as "why shouldn't I make all my parameters of type object
"? 它基本上与“为什么不让我的所有参数都成为
object
类型”相同? Sure, you could do that. 当然可以。 And if you do that, casting back wherever needed, your code would work.
如果这样做,则可以在需要的地方回退,您的代码将起作用。 But I know I prefer
但我知道我更喜欢
long Add(long x, long y) { return x + y; }
over 过度
object Add(object x, object y) { return (long)x + (long)y; }
and I suspect that in this case, you do too. 我怀疑在这种情况下,您也这样做。 Yet this is exactly what you're doing when you make the parameter type
EventArgs
rather than Common.WinLose_ProgressStage
. 但是,这正是在使参数类型为
EventArgs
而不是Common.WinLose_ProgressStage
时正在执行的操作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.