在以通用方式调用事件之前,是否有任何明智的方法来避免测试事件的无效性?很明显,如果我打电话给一名代表,我希望它得到分配。
(如果我真的想/需要测试它的无效性,我最终可以显式地做它,但是系统地进行这个测试有点乏味和冗长。)
public delegate void ResetTradesDelegate();
public ResetTradesDelegate ResetTradesEvents;
public void OnSessionRxAdmMessage(IVfxFixAppSession session, FixMessage msg)
{
if (ResetTradesEvent != null) //<-- Is there "any" a way not to write this test explicitly for each delegate ?
ResetTradesEvent();
}发布于 2012-07-12 20:30:11
public event EventHandler NoDataEventHandler = delegate{};以这种方式声明一个事件意味着它永远不会是空的。至少,它总是有一个单独的非op事件处理程序。
在你的情况下,可能
public event ResetTradesDelegate ResetTradesEvents = delegate{};触发事件总是会有与其相关联的竞赛条件。当委托为null时,您可能会冒调用它的风险,或者在事件取消后调用委托。Eric写了一篇关于这个主题的相当全面的文章,here。上面的技术仍然受到第二种竞争条件的影响,因此事件处理程序需要在事件被解钩后对被调用具有鲁棒性。
发布于 2012-07-12 20:39:32
static void CallIfNotNull(this Action action)
{
if (action != null) action();
}作为一种扩展方法,这是相当方便的使用。
发布于 2012-07-12 21:03:12
可以使用始终订阅的no事件创建事件处理程序:
public class MyClass
{
public MyClass()
{
this.Event += (sender, e) => ();
}
public event EventHandler Event;
protected virtual void OnEvent()
{
this.Event(this, EventArgs.Empty);
}
}但是,这需要订阅您的事件,并将导致性能损失,因为在订阅事件处理程序列表中仍将存在无操作委托。
这里我的首选是创建一对扩展方法来调用任何事件处理程序,同时执行空安全检查:
public static void Raise(this EventHandler @event, object sender)
{
if(@event != null)
{
@event.Invoke(sender, EventArgs.Empty);
}
}
public static void Raise<TEventArgs>(
this EventHandler<TEventArgs> @event,
object sender,
TEventArgs args)
where TEventArgs : EventArgs
{
if(@event != null)
{
@event.Invoke(sender, args);
}
}然后,可以很容易地在库中的任何地方调用它来安全地引发事件:
this.ResetTradesEvent.Raise(this);这纯粹是语法上的“糖”;您仍然在检查委托。然而,这是一种很好的、可重用的方式来结束C#语言的这一难闻的部分。
https://stackoverflow.com/questions/11459813
复制相似问题