pet*_*757 5 c# system.reactive
我有一个看起来像这样的代表:
public delegate void MyDelegate(int arg1, int arg2);
Run Code Online (Sandbox Code Playgroud)
一个看起来像这样的事件:
public event MyDelegate SomethingHappened;
Run Code Online (Sandbox Code Playgroud)
是否有一些简单的方法为此事件创建IObservable序列?我想做这样的事情(但它不会编译):
var obs = Observable.FromEventPattern<int, int>(this, "SomethingHappened");
var subscription = obs.Subscribe(x,y => DoSomething(x, y));
Run Code Online (Sandbox Code Playgroud)
....
private void DoSomething(int value1, int value2)
{
...
}
Run Code Online (Sandbox Code Playgroud)
有一种方法可以使用Observable.FromEvent
如下方法.
让我们创建一个类Test
来封装委托和事件定义:
public class Test
{
public delegate void MyDelegate(int arg1, int arg2);
public event MyDelegate SomethingHappened;
public void RaiseEvent(int a, int b)
{
var temp = SomethingHappened;
if(temp != null)
{
temp(a, b);
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在,因为委托有两个没有整齐地打包到子类中的参数EventArgs
,我们必须使用转换函数将它们打包成合适的包含类型.如果你记得OnNext
方法的签名IObservable
应该清楚为什么我们必须这样做 - 我们只能在这里提供一个参数.
你可以为此创建自己的类型,但我会懒惰并使用Tuple<int,int>
.然后我们可以使用Observable.FromEvent
转换函数的重载,如下所示:
var test = new Test();
var obs = Observable.FromEvent<Test.MyDelegate, Tuple<int,int>>(
handler => (a, b) => handler(Tuple.Create(a,b)),
h => test.SomethingHappened += h,
h => test.SomethingHappened -= h
);
Run Code Online (Sandbox Code Playgroud)
为了清楚起见,我们在第一个参数中提供的是一个函数,它接受一个OnNext处理程序(在这种情况下是类型Action<Tuple<int,int>>
)并返回一个可以订阅事件(类型MyDelegate
)的委托.将为每个事件调用此委托,并依次调用从Subscribe
调用传入的OnNext处理程序.因此,我们最终会得到一个类型的流IObservable<Tuple<int,int>>
.
有了obs,我们可以这样订阅:
var subscription = obs.Subscribe(x => Console.WriteLine(x.Item1 + " " + x.Item2));
Run Code Online (Sandbox Code Playgroud)
并测试:
test.RaiseEvent(1, 2);
Run Code Online (Sandbox Code Playgroud)