单次事件订阅 [英] Single-shot event subscription

查看:137
本文介绍了单次事件订阅的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我相当确信,这是不可能的,但我要问不过。

为了使单次认购活动,我经常发现自己使用这个(自主发明)模式:

 事件处理程序处理程序= NULL;
处理器=(发件人,E)=>
{
    SomeEvent - =处理程序;
    初始化();
};
SomeEvent + =处理程序;

这是相当多的锅炉板,而这也使得关于修改关闭ReSharper的whinge。有没有把这个模式变成一个扩展方法或类似的方法吗?这样做的更好的办法?

在理想情况下,我想是这样的:

  SomeEvent.OneShot(句柄)


解决方案

这不是很容易重构为一个扩展方法,因为你可以参考在C#中的事件的唯一途径是通过订阅( + = )或退订( - 。= )从它(除非它在当前类的声明)

您可以用同样的方法,因为在无扩展:的 Observable.FromEvent 需要两个代表从它订阅事件退订。所以,你可以做这样的事情:

 公共静态类EventHelper
{
    公共静态无效SubscribeOneShot(
        动作<&事件处理GT;订阅,
        动作<&事件处理GT;退订,
        事件处理程序处理程序)
    {
        事件处理actualHandler = NULL;
        actualHandler =(发件人,E)=>
        {
            退订(actualHandler);
            处理器(发件人,E);
        };
        订阅(actualHandler);
    }
}...美孚F =新的Foo();
EventHelper.SubscribeOneShot(
    处理器= GT; f.Bar + =处理程序,
    处理器= GT; f.Bar - =处理程序,
    (发件人,E)=> { /* 随你 */ });

I'm fairly convinced that this isn't possible, but I'm going to ask nonetheless.

In order to make a single-shot subscription to events, I frequently find myself using this (self-invented) pattern:

EventHandler handler=null;
handler = (sender, e) =>
{
    SomeEvent -= handler;
    Initialize();
};
SomeEvent += handler;

It's quite a lot of boiler-plate, and it also makes Resharper whinge about modified closures. Is there a way of turning this pattern into an extension method or similar? A better way of doing it?

Ideally, I'd like something like:

SomeEvent.OneShot(handler)

解决方案

It's not very easy to refactor to an extension method, because the only way you can refer to an event in C# is by subscribing (+=) to or unsubscribing (-=) from it (unless it's declared in the current class).

You could use the same approach as in Reactive Extensions: Observable.FromEvent takes two delegates to subscribe to the event an unsubscribe from it. So you could do something like that:

public static class EventHelper
{
    public static void SubscribeOneShot(
        Action<EventHandler> subscribe,
        Action<EventHandler> unsubscribe,
        EventHandler handler)
    {
        EventHandler actualHandler = null;
        actualHandler = (sender, e) =>
        {
            unsubscribe(actualHandler);
            handler(sender, e);
        };
        subscribe(actualHandler);
    }
}

...

Foo f = new Foo();
EventHelper.SubscribeOneShot(
    handler => f.Bar += handler,
    handler => f.Bar -= handler,
    (sender, e) => { /* whatever */ });

这篇关于单次事件订阅的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆