?-6ren"> ?-这就是我的意思。假设我正在使用公开事件的 API,但这些事件不遵循标准 EventHandler或EventHandler签名。例如,一个事件可能如下所示: Public Event Update(B-6ren">
gpt4 book ai didi

.net - 如何从 "non-standard"事件中获取 Rx 中的 IObservable

转载 作者:行者123 更新时间:2023-12-02 08:38:20 25 4
gpt4 key购买 nike

这就是我的意思。假设我正在使用公开事件的 API,但这些事件不遵循标准 EventHandlerEventHandler<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 (即 UpdateEventArgs ),编写另一个类来包装提供 Update 的对象事件,为包装类提供其自己的 Update事件是 EventHandler<UpdateEventArgs> ,并获得 IObservable<UpdateEventArgs>来自那个。但这是一项烦人的工作量。

有没有办法创建 IObservable<[something]>来自这样的“非标准”事件,还是我运气不好?

<小时/>

更新:从 Jon Skeet 的回答中,我被推向了以下重载的方向 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,如果不编写自己的方法,确实无法完成上述任务?

我几乎感觉自己一开始就从完全错误的角度来处理这个问题。但我真的不确定。

最佳答案

也许您可以为自定义事件签名添加您自己的实现?

public interface ICustomEvent<TSource, TArgs>
{
public TSource Source { get; }
public TArgs EventArgs { get; }
}

public interface CustomEvent<TSource, TArgs> : ICustomEvent<TSource, TArgs>
{
public TSource Source { get; set; }
public TArgs EventArgs { get; set; }
}

public static class ObservableEx
{
public static IObservable<ICustomEvent<TSource, TArgs>> FromCustomEvent(
Action<Action<TSource, TArgs>> addHandler,
Action<Action<TSource, TArgs>> removeHandler)
{
return Observable.CreateWithDisposable(observer =>
{
Action<TSource, TArgs> eventHandler = (s,a) =>
observer.OnNext(new CustomEvent<TSource,TArgs>(s,a));

addHandler(eventHandler);

return Disposable.Create(() => removeHandler(eventHandler));
});
}
}

然后您可以将其用作:

var observable = ObservableEx.FromCustomEvent<BaseSubscription,BaseEvent>(
h => updateSource.Update += h,
h => updateSource.Update -= h
);

关于.net - 如何从 "non-standard"事件中获取 Rx 中的 IObservable<T>?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2915051/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com