这就是我的意思。假设我正在使用一个公开事件的 API,但这些事件不遵循标准EventHandler
或EventHandler<TEventArgs>
签名。一个事件可能如下所示,例如:
Public Event Update(ByVal sender As BaseSubscription, ByVal e As BaseEvent)
现在,通常,如果我想IObservable<TEventArgs>
从事件中获取一个,我可以这样做:
Dim updates = Observable.FromEvent(Of UpdateEventArgs)( _
target:=updateSource, _
eventName:="Update" _
)
但这行不通,因为Update
事件不是EventHandler<UpdateEventArgs>
——事实上,没有——它UpdateEventArgs
基本上只是它自己的事情。
显然,我可以定义我自己的派生自EventArgs
(ie, UpdateEventArgs
) 的类,编写另一个类来包装提供Update
事件的对象,为包装类提供它自己的 Update
事件,即an EventHandler<UpdateEventArgs>
,并从中IObservable<UpdateEventArgs>
获取an。但这是令人讨厌的工作量。
有什么方法可以IObservable<[something]>
从这样的“非标准”事件中创建一个,还是我不走运?
更新:从乔恩斯基特的回答中,我被推向以下重载的方向Observable.FromEvent
:
Function FromEvent(Of TDelegate, TEventArgs As EventArgs)( _
conversion As Func(Of EventHandler(Of TEventArgs), TDelegate), _
addHandler As Action(Of TDelegate), _
removeHandler As Action(Of TDelegate) _
) As IObservable(Of IEvent(Of TEventArgs))
不过,我不得不承认,我很难理解那Func(Of EventHandler(Of TEventArgs), TDelegate)
部分。这对我来说似乎倒退了(?)。显然,我只是缺少一些东西......
无论如何,如果它有帮助,我认为这就是等效的 C# 代码的样子(老实说:我不确定这一点。尽管我自己通常更喜欢 C#,但这段代码是一个人的工作我的同事,他们主要用 VB.NET 编写;而 VB.NET 允许使用多种语法来声明事件):
// notice: not an EventHandler<TEventArgs>
public delegate void UpdateEventHandler(BaseSubscription sender, BaseEvent e);
// not 100% sure why he did it this way
public event UpdateEventHandler Update;
这里棘手的部分是,似乎某种派生类EventArgs
是必要的,无论如何。在我正在使用的 API 中,没有这样的类。所以,最起码,我得写一个。但这应该是相当微不足道的(基本上是一个属性:)BaseEvent
。
最后,我假设这个重载所需的代码在 C# 中看起来像这样:
var updates = Observable.FromEvent<UpdateEventHandler, UpdateEventArgs>(
// conversion (Func<EventHandler<UpdateEventArgs>, UpdateEventHandler>)
handler => (sender, e) => handler(sender, new UpdateEventArgs(e)),
// addHandler (Action<UpdateEventHandler>)
handler => updateSource.Update += handler,
// removeHandler (Action<UpdateEventHandler>)
handler => updateSource.Update -= handler
);
首先:我有这个直吗?其次:我是否正确地说使用 VB 9,如果不编写自己的方法就真的无法完成上述任务吗?
我几乎觉得我一开始就从完全错误的角度来处理这个问题。但我真的不确定。