首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >EventHandler<T>和EventHandler

EventHandler<T>和EventHandler
EN

Stack Overflow用户
提问于 2016-12-20 09:44:38
回答 3查看 7K关注 0票数 2

我想问一下EventHandlerEventHandler<T>之间的区别。

以前,我已经实现了一个EventHandler,它有一个自定义的EventArgs,可以从用户控件传递到父页面。

我想我需要应用EventHandler< T >,但是它可以通过EventHandler来实现。(事实上,当我试图应用EventHandler<T>时,会出现奇怪的错误,程序是工作的,但是在IDE中显示了错误,但我无法解决[C# Custom EventHandler ])。

因此,我想知道在什么情况下我需要应用EventHandler < T >

代码语言:javascript
复制
public event EventHandler AppendProcess;
public event EventHandler<MyEventArg> AppendProcess;

--更新--我就是这样在用户控件中调用事件的(正如我所说的,我可以通过这样做将对象传递给父页面(尽管我不知道这样做是否正确)

代码语言:javascript
复制
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));
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-12-20 09:50:49

EventHandler<T>只是一个通用的EventHandler类型,它避免了您必须为想要使用的每一种EventArgs声明一个新的委托类型。

Control.KeyPress为例。它被声明为KeyPressEventHandler类型的事件。该代表刚刚被宣布为:

代码语言:javascript
复制
public delegate void KeyPressEventHandler(object sender, KeyPressEventArgs e)

如果EventHandler<T> (和泛型)在创建时已经存在,则可以将事件声明为EventHandler<KeyPressEventArgs>,从而保存委托声明。有许多类似于EventHandler的委托,它们只在第二个参数的类型上有所不同-- EventHandler<T>避免了这种冗余。

不,如果您没有自己的自定义EventArgs子类,就没有理由使用EventHandler<T>.但是如果您这样做了,最好使用它,以便处理事件的方法以强类型的方式接收您的自定义EventArgs子类。

另外,调用事件处理程序的方式并不是线程安全的。在进行无效检查后,另一个线程可以取消订阅最后的事件处理程序。如果使用的是C# 5,则应将其编写为:

代码语言:javascript
复制
var handler = AppendProcess;
if (handler != null)
{
    handler(this, new Common.WinLose_ProgressStage(...));
}

如果使用的是C# 6或更高版本,则可以使用空条件运算符:

代码语言:javascript
复制
// If AppendProcess is null, the arguments won't even be evaluated
AppendProcess?.Invoke(this, new Common.WinLose_ProgressStage(...));
票数 8
EN

Stack Overflow用户

发布于 2016-12-20 09:52:13

EventHandler<T>EventHandler的泛型变体。通常,您会重写EventArgsEventHandler来生成自己的事件类型。如果要将自定义属性传递给e参数,仍然需要派生e,但不再需要为EventHandler创建自定义委托。你现在可以说:

代码语言:javascript
复制
public event EventHandler<SomeEventArgs> SomeEvent;

比以下更方便:

代码语言:javascript
复制
public delegate void SomeEventHandler(object sender, SomeEventArgs e);

public event SomeEventHandler SomeEvent;

当您的委托签名没有改变时,EventHandler<T>的使用要简单得多。

票数 4
EN

Stack Overflow用户

发布于 2016-12-20 09:52:15

从你的另一个问题:

Common.WinLose_ProgressStage wps = (Common.WinLose_ProgressStage)e;

这是一个可能会失败的强制转换,这取决于方法的调用方式。没有什么可以保证您的事件处理程序只使用Common.WinLose_ProgressStage调用,而无需检查完整的程序就可以进行检查。也可以使用普通的EventArgs来调用它:通过使参数类型为EventArgs使之成为可能。

EventHandler<T>会导致更多的编译时类型检查.如果其他代码试图传入EventArgs.Empty,则调用将无法编译。

这基本上和“为什么我不应该设置object类型的所有参数”一样?当然,你可以这么做。如果您这样做,在任何需要的地方返回,您的代码就会工作。但我知道我更喜欢

代码语言:javascript
复制
long Add(long x, long y) { return x + y; }

结束

代码语言:javascript
复制
object Add(object x, object y) { return (long)x + (long)y; }

我怀疑在这种情况下,你也是。然而,当您使参数类型为EventArgs而不是Common.WinLose_ProgressStage时,这正是您所要做的。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41239191

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档