代码之家  ›  专栏  ›  技术社区  ›  jonnii

在使用块期间订阅事件

c#
  •  2
  • jonnii  · 技术社区  · 15 年前

    我经常遇到以下代码:

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

    这很好,但如果我们能用更好的方式来做就好了。我想做一些类似的事情:

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

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

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

    很明显,我不喜欢使用“using”语法,有争议的是,你可以说这是对语言的曲解。其他选择将不胜感激!

    2 回复  |  直到 15 年前
        1
  •  2
  •   PeterAllenWebb    15 年前

        2
  •  2
  •   Joel Mueller    15 年前

    也许有一种更简洁的语法可以做到这一点,但是如果你有一个这样的结构。。。

    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();
    }