我想问一下EventHandler和EventHandler<T>之间的区别。
以前,我已经实现了一个EventHandler,它有一个自定义的EventArgs,可以从用户控件传递到父页面。
我想我需要应用EventHandler< T >,但是它可以通过EventHandler来实现。(事实上,当我试图应用EventHandler<T>时,会出现奇怪的错误,程序是工作的,但是在IDE中显示了错误,但我无法解决[C# Custom EventHandler ])。
因此,我想知道在什么情况下我需要应用EventHandler < T >?
public event EventHandler AppendProcess;
public event EventHandler<MyEventArg> AppendProcess;--更新--我就是这样在用户控件中调用事件的(正如我所说的,我可以通过这样做将对象传递给父页面(尽管我不知道这样做是否正确)
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));发布于 2016-12-20 09:50:49
EventHandler<T>只是一个通用的EventHandler类型,它避免了您必须为想要使用的每一种EventArgs声明一个新的委托类型。
以Control.KeyPress为例。它被声明为KeyPressEventHandler类型的事件。该代表刚刚被宣布为:
public delegate void KeyPressEventHandler(object sender, KeyPressEventArgs e)如果EventHandler<T> (和泛型)在创建时已经存在,则可以将事件声明为EventHandler<KeyPressEventArgs>,从而保存委托声明。有许多类似于EventHandler的委托,它们只在第二个参数的类型上有所不同-- EventHandler<T>避免了这种冗余。
不,如果您没有自己的自定义EventArgs子类,就没有理由使用EventHandler<T>.但是如果您这样做了,最好使用它,以便处理事件的方法以强类型的方式接收您的自定义EventArgs子类。
另外,调用事件处理程序的方式并不是线程安全的。在进行无效检查后,另一个线程可以取消订阅最后的事件处理程序。如果使用的是C# 5,则应将其编写为:
var handler = AppendProcess;
if (handler != null)
{
handler(this, new Common.WinLose_ProgressStage(...));
}如果使用的是C# 6或更高版本,则可以使用空条件运算符:
// If AppendProcess is null, the arguments won't even be evaluated
AppendProcess?.Invoke(this, new Common.WinLose_ProgressStage(...));发布于 2016-12-20 09:52:13
EventHandler<T>是EventHandler的泛型变体。通常,您会重写EventArgs和EventHandler来生成自己的事件类型。如果要将自定义属性传递给e参数,仍然需要派生e,但不再需要为EventHandler创建自定义委托。你现在可以说:
public event EventHandler<SomeEventArgs> SomeEvent;比以下更方便:
public delegate void SomeEventHandler(object sender, SomeEventArgs e);
public event SomeEventHandler SomeEvent;当您的委托签名没有改变时,EventHandler<T>的使用要简单得多。
发布于 2016-12-20 09:52:15
从你的另一个问题:
Common.WinLose_ProgressStage wps = (Common.WinLose_ProgressStage)e;
这是一个可能会失败的强制转换,这取决于方法的调用方式。没有什么可以保证您的事件处理程序只使用Common.WinLose_ProgressStage调用,而无需检查完整的程序就可以进行检查。也可以使用普通的EventArgs来调用它:通过使参数类型为EventArgs使之成为可能。
EventHandler<T>会导致更多的编译时类型检查.如果其他代码试图传入EventArgs.Empty,则调用将无法编译。
这基本上和“为什么我不应该设置object类型的所有参数”一样?当然,你可以这么做。如果您这样做,在任何需要的地方返回,您的代码就会工作。但我知道我更喜欢
long Add(long x, long y) { return x + y; }结束
object Add(object x, object y) { return (long)x + (long)y; }我怀疑在这种情况下,你也是。然而,当您使参数类型为EventArgs而不是Common.WinLose_ProgressStage时,这正是您所要做的。
https://stackoverflow.com/questions/41239191
复制相似问题