[英]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.