首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >自测试委托:避免在调用前检查null?

自测试委托:避免在调用前检查null?
EN

Stack Overflow用户
提问于 2012-07-12 20:10:31
回答 5查看 6.8K关注 0票数 9

在以通用方式调用事件之前,是否有任何明智的方法来避免测试事件的无效性?很明显,如果我打电话给一名代表,我希望它得到分配。

(如果我真的想/需要测试它的无效性,我最终可以显式地做它,但是系统地进行这个测试有点乏味和冗长。)

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

回答 5

Stack Overflow用户

回答已采纳

发布于 2012-07-12 20:30:11

代码语言:javascript
复制
public event EventHandler NoDataEventHandler = delegate{};

以这种方式声明一个事件意味着它永远不会是空的。至少,它总是有一个单独的非op事件处理程序。

在你的情况下,可能

代码语言:javascript
复制
public event ResetTradesDelegate ResetTradesEvents = delegate{};

触发事件总是会有与其相关联的竞赛条件。当委托为null时,您可能会冒调用它的风险,或者在事件取消后调用委托。Eric写了一篇关于这个主题的相当全面的文章,here。上面的技术仍然受到第二种竞争条件的影响,因此事件处理程序需要在事件被解钩后对被调用具有鲁棒性。

票数 15
EN

Stack Overflow用户

发布于 2012-07-12 20:39:32

代码语言:javascript
复制
static void CallIfNotNull(this Action action)
{
 if (action != null) action();
}

作为一种扩展方法,这是相当方便的使用。

票数 4
EN

Stack Overflow用户

发布于 2012-07-12 21:03:12

可以使用始终订阅的no事件创建事件处理程序:

代码语言:javascript
复制
public class MyClass
{
    public MyClass()
    {
        this.Event += (sender, e) => ();
    }

    public event EventHandler Event;

    protected virtual void OnEvent()
    {
        this.Event(this, EventArgs.Empty);
    }
}

但是,这需要订阅您的事件,并将导致性能损失,因为在订阅事件处理程序列表中仍将存在无操作委托。

这里我的首选是创建一对扩展方法来调用任何事件处理程序,同时执行空安全检查:

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

然后,可以很容易地在库中的任何地方调用它来安全地引发事件:

代码语言:javascript
复制
this.ResetTradesEvent.Raise(this);

这纯粹是语法上的“糖”;您仍然在检查委托。然而,这是一种很好的、可重用的方式来结束C#语言的这一难闻的部分。

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

https://stackoverflow.com/questions/11459813

复制
相关文章

相似问题

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