簡體   English   中英

Observable.FromEventPattern(addHandler,removeHandler)-簡化嗎?

[英]Observable.FromEventPattern(addHandler, removeHandler ) - simplification?

從事件創建可觀察對象時,以下是最常見的方法:

var o = Observable.FromEventPattern(h => source.Event += h,
                                    h => source.Event -= h);

在某些情況下,我希望以相同的方式處理多個事件,因此這種形式有點乏味。 但這看起來並不容易,因為事件本身似乎無法進行參數化,如下面的非編譯代碼所示:

private IObservable MakeAnObservableFromThisEvent(Event event)
{
    return Observable.FromEventPattern(h => event += h,
                                        h => event -= h);

}

private void MakeAlotOfObservables(object source)
{
    MakeAnObservableFromThisEvent(source.OneEvent);
    MakeAnObservableFromThisEvent(source.AnotherEvent);
    MakeAnObservableFromThisEvent(source.ThirdEvent);

    //or even
    MakeAnObservableFromThisEvent(() => source.ThirdEvent);
}

原因是“事件名稱”超載:

var o = Observable.FromEventPattern< >(source, "Event");

但是這東西或多或少都有魔力弦...

是否有優化此代碼的余地? 還是這就是事情的樣子?

問題在於事件處理程序具有“值類型”語義(例如字符串),因此僅當您打算調用它們時將它們作為參數傳遞才有用。 有效地添加新的處理程序會創建一個新的委托實例,並且原始實例不會被修改。

然后,唯一真正可行的方法是同時添加和刪除處理程序並保持類型安全,這是您在問題中首先顯示的語法。

var o =
    Observable
        .FromEventPattern(
            h => source.Event += h,
            h => source.Event -= h);

但是,還有一個我使用了很多選項的方法-使用擴展方法。

如果我有這堂課:

public class Foo
{
    public event EventHandler<EventArgs> Click;
}

我可以寫一個擴展方法:

public static class FooEx
{
    public static IObservable<EventPattern<EventArgs>> Clicks(this Foo source)
    {
        return
            Observable
                .FromEventPattern<EventArgs>(
                    h => source.Click += h,
                    h => source.Click -= h);
    }
}

然后,我可以這樣寫:

var foo = new Foo();
foo.Clicks().Subscribe(x => Console.WriteLine("Click!"));

您可以為每個類型和事件有效地編寫一次擴展方法,然后可以在需要時使用它,並使用大大改進的語法。

這並不是一個直接的解決方案,但是ReactiveUI-Events基本上實現了@Enigmativity對整個框架的建議。 因此,您可以執行以下操作:

Observable.Merge(
    Foo.Events().Clicked.Select(_ => Unit.Default),
    Foo.Events().KeyUp.Select(_ => Unit.Default));

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM