在使用块的持续时间内订阅事件

时间:2009-06-12 18:15:44

标签: c#

我经常遇到以下代码:

myService.SomeEvent += listener;
myService.DoSomething();
myService.SomeEvent -= listener;

这很好,但如果我们能以更好的方式做到这一点,那就太好了。我在想做类似的事情:

using(EventScope.Start(myService.SomeEvent, listener)){
    myService.DoSomething();
}

不幸的是,C#禁止这样做,因为myService.SomeEvent只能出现在+ =或a - =的左侧(有充分理由)。我的问题是我还有其他选择吗?理想情况下,我希望这是类型安全的,它排除反射并执行以下操作(我已经实现了):

using(EventScope.Start(myService, "SomeEvent", listener){
    myService.DoSomething();
}

要明确我没有使用'使用'语法,并且可以说你可以说这是对语言的歪曲。其他选择将不胜感激!

2 个答案:

答案 0 :(得分:2)

您是否担心因为异常或某事而不会取消订阅?如果是这样,你可以使用try / finally。否则,我认为最初的方式是最好的,对我来说看起来很好。

答案 1 :(得分:2)

使用更清晰的语法可能有一种方法可以做到这一点,但是如果你有这样的结构......

public struct ActionDisposable : IDisposable
{
    private readonly Action _action;

    public ActionDisposable(Action action)
    {
        _action = action;
    }

    public void Dispose()
    {
        _action();
    }
}

......和这样的方法:

public static IDisposable EventScope(Action subscribe, Action unsubscribe)
{
    subscribe();
    return new ActionDisposable(unsubscribe);
}

那会让你编写这样的代码:

using (EventScope(() => myService.SomeEvent += listener, () => myService.SomeEvent -= listener))
{
    myService.DoStuff();
}

或者像这样:

myService.SomeEvent += listener
using (new ActionDisposable(() => myService.SomeEvent -= listener))
{
    myService.DoStuff();
}