Observable是.NET中的第一類類型 - 這意味着您可以保留對它們的引用並將它們作爲參數傳遞給您喜歡的任何構造函數/方法。
活動是不是一流的類型。它們只能在可以引用其包含對象的範圍內附加和分離。
因此,這意味着我不能做到這一點:
public void SomeMethod(EventHandler handler)
{
handler += (s, e) => { /* Handler Code */ };
}
public void SomeOtherMethod()
{
SomeMethod(Application.Current.Activated);
}
如果我嘗試,我得到的錯誤:
The event 'Application.Activated' can only appear on the left hand side of += or -=
這應該讓你知道你爲什麼不能做var appActivated = Observable.FromEvent(Application.Current.Activated);
。
那麼,我怎樣才能解決這個問題附加SomeMethod
事件?
方法如下:
public void SomeMethod(Action<EventHandler> addHandler)
{
addHandler((s, e) => { /* Handler Code */ });
}
public void SomeOtherMethod()
{
SomeMethod(h => Application.Current.Activated += h);
}
基本上,SomeMethod
參數不再EventHandler
,但Action<EventHandler>
方法。這意味着我不再試圖傳遞事件本身 - 而是傳遞一種方式讓被調用的代碼將自己附加到我的事件中。撥打SomeMethod
的h
是承諾如果我將來有一個有效的處理程序,那麼我可以通過調用Action<EventHandler>
來附加它。
因此,讓我們說我現在想寫一些代碼,知道如何附加和從事件分離。我現在需要這個代碼:
public void SomeMethod(Action<EventHandler> addHandler, Action<EventHandler> removeHandler)
{
EventHandler handler = (s, e) => { /* Handler Code */ };
addHandler(handler);
/* Some Intervening Code */
removeHandler(handler);
}
public void SomeOtherMethod()
{
SomeMethod(h => Application.Current.Activated += h, h => Application.Current.Activated -= h);
}
在/* Some Intervening Code */
代碼附加處理程序,並且它取出來之後。
這給我們帶來了你的代碼在你的問題:
var appActivated = Observable.FromEvent(
h => Application.Current.Activated += h,
h => Application.Current.Activated -= h);
這在很大程度上與上面相同的SomeMethod
呼叫 - FromEvent
需要爲它附加和從事件分離的方式。 h
是一個承諾,說:「嘿,FromEvent
,如果你可以提供一個處理程序,當你將來需要它時,我保證這個代碼將正確地附加它。」或者,根據具體情況分離。
現在,只是有點迂腐,你的代碼實際上應該是:
IObservable<EventPattern<EventArgs>> appActivated =
Observable
.FromEventPattern<EventHandler, EventArgs>(
h => Application.Current.Activated += h,
h => Application.Current.Activated -= h);
現在,我有一個IObservable<EventPattern<EventArgs>>
我可以重寫SomeMethod
藉此作爲參數,並把它寫這樣的:
public IDisposable SomeMethod(IObservable<EventPattern<EventArgs>> appActivated)
{
return appActivated.Subscribe(ep => { /* Handler Code */ });
}
現在可以看到Rx的所有功能。 .Subscribe
方法不需要任何對原始事件包含對象的引用,但它最終將調用h => Application.Current.Activated += h
附加,並在需要時分離。現在,我可以有效地將事件作爲.NET中的第一類類型傳遞。
我寫了一個很長的解釋和討論的FromEvent一會兒,可能是有用的:http://stackoverflow.com/questions/19895373/how-to-use-observable-fromevent-instead-of-fromeventpattern-and -avoid-string-lit/19896246#19896246 –
@詹姆斯世界:在閱讀答案後,我有60-70%的理解。閱讀你的文章後,它大於95%。特別是您的段落以「注意,這只是調用訂閱創建訂閱的行爲」。幫了我很多。 – Bad
感謝您的反饋。這是一個令人驚訝的深層方法,需要大量的解釋! –