与委托具有多个参数且没有 EventArgs 的事件集成
Integration with event where the delegate has more than one argument and there are no EventArgs
FromEvent
或 FromEventPattern
方法似乎没有重载,只有在有更多的情况下才会将 IObservable<T>
类型为 TDelegate
的事件转换为不止一个参数而且没有 EventArgs
.
例如看来我们无法将以下内容转换为可观察对象。
public event Action<int, int> SomethingHappened;
public event Func<string, int> SomethingElseHappened;
我们要么必须在某处有一个EventArgs
,要么有一个TDelegate
,其签名中只有一个参数。因此,以下是可转换的,因为它们的隐式委托中有一个 EventArgs
。
public event NameChangedHandler NameChanged;
public event EventHandler RollNumberChanged;
public event EventHandler<AgeChangedEventArgs> AgeChanged;
public delegate void NameChangedHandler(
object sender,
NameChangedEventArgs e);
而这个也可以转换,因为它的参数中只有一个T
。
public event Action<Tuple<string, string>> ClassChanged;
如果遇到这样的事件我该怎么办:
public event Action<T1, T2...> ItHappened;
使用 class 测试仪
public class Tester
{
public void FireEvent(int i1, int i2, int i3)
{
if(ItHappened != null)
ItHappened(i1, i2, i3);
}
public event Action<int, int, int> ItHappened;
}
您可以将此签名 Observable.FromEvent<TDelegate, TEventArgs> (Func<Action<TEventArgs>, TDelegate>, Action<TDelegate>, Action<TDelegate>)
与转换函数一起使用,如下所示:
var t3 = new Tester();
IObservable<Tuple<int, int, int>> observable = Observable.FromEvent<Action<int, int, int>, Tuple<int, int, int>>(
onNextHandler => (int i1, int i2, int i3) => onNextHandler(Tuple.Create(i1, i2, i3)),
h => t3.ItHappened += h,
h => t3.ItHappened -= h);
using (var disposable = observable.Subscribe(t => Console.WriteLine($"{{{t.Item1}, {t.Item2}, {t.Item3}}}")))
{
t3.FireEvent(1, 2, 3);
}
t3.FireEvent(1, 2, 3);
关于该重载有很好的参考 here。
我必须说我在事件 public event Func<string, int> SomethingElseHappened;
上遇到了困难,但这是一个奇怪的事件,其中事件实际上 returns 一个值。
使用 public event Action<int, int> SomethingHappened;
,但是使用 FromEvent
就很容易了。
鉴于此 class:
public class Foo
{
public event Action<int, int> SomethingHappened;
public void OnSomethingHappened(int x, int y)
{
this.SomethingHappened?.Invoke(x, y);
}
}
...然后这个代码:
var foo = new Foo();
var fooSomethingHappened =
Observable
.FromEvent<Action<int, int>, Tuple<int, int>>(
a => (x, y) => a(Tuple.Create(x, y)),
h => foo.SomethingHappened += h,
h => foo.SomethingHappened -= h);
fooSomethingHappened
.Subscribe(t =>
Console.WriteLine("SomethingHappened: {0} & {1}", t.Item1, t.Item2));
foo.OnSomethingHappened(3, 5);
...给我们:
SomethingHappened: 3 & 5
FromEvent
或 FromEventPattern
方法似乎没有重载,只有在有更多的情况下才会将 IObservable<T>
类型为 TDelegate
的事件转换为不止一个参数而且没有 EventArgs
.
例如看来我们无法将以下内容转换为可观察对象。
public event Action<int, int> SomethingHappened;
public event Func<string, int> SomethingElseHappened;
我们要么必须在某处有一个EventArgs
,要么有一个TDelegate
,其签名中只有一个参数。因此,以下是可转换的,因为它们的隐式委托中有一个 EventArgs
。
public event NameChangedHandler NameChanged;
public event EventHandler RollNumberChanged;
public event EventHandler<AgeChangedEventArgs> AgeChanged;
public delegate void NameChangedHandler(
object sender,
NameChangedEventArgs e);
而这个也可以转换,因为它的参数中只有一个T
。
public event Action<Tuple<string, string>> ClassChanged;
如果遇到这样的事件我该怎么办:
public event Action<T1, T2...> ItHappened;
使用 class 测试仪
public class Tester
{
public void FireEvent(int i1, int i2, int i3)
{
if(ItHappened != null)
ItHappened(i1, i2, i3);
}
public event Action<int, int, int> ItHappened;
}
您可以将此签名 Observable.FromEvent<TDelegate, TEventArgs> (Func<Action<TEventArgs>, TDelegate>, Action<TDelegate>, Action<TDelegate>)
与转换函数一起使用,如下所示:
var t3 = new Tester();
IObservable<Tuple<int, int, int>> observable = Observable.FromEvent<Action<int, int, int>, Tuple<int, int, int>>(
onNextHandler => (int i1, int i2, int i3) => onNextHandler(Tuple.Create(i1, i2, i3)),
h => t3.ItHappened += h,
h => t3.ItHappened -= h);
using (var disposable = observable.Subscribe(t => Console.WriteLine($"{{{t.Item1}, {t.Item2}, {t.Item3}}}")))
{
t3.FireEvent(1, 2, 3);
}
t3.FireEvent(1, 2, 3);
关于该重载有很好的参考 here。
我必须说我在事件 public event Func<string, int> SomethingElseHappened;
上遇到了困难,但这是一个奇怪的事件,其中事件实际上 returns 一个值。
使用 public event Action<int, int> SomethingHappened;
,但是使用 FromEvent
就很容易了。
鉴于此 class:
public class Foo
{
public event Action<int, int> SomethingHappened;
public void OnSomethingHappened(int x, int y)
{
this.SomethingHappened?.Invoke(x, y);
}
}
...然后这个代码:
var foo = new Foo();
var fooSomethingHappened =
Observable
.FromEvent<Action<int, int>, Tuple<int, int>>(
a => (x, y) => a(Tuple.Create(x, y)),
h => foo.SomethingHappened += h,
h => foo.SomethingHappened -= h);
fooSomethingHappened
.Subscribe(t =>
Console.WriteLine("SomethingHappened: {0} & {1}", t.Item1, t.Item2));
foo.OnSomethingHappened(3, 5);
...给我们:
SomethingHappened: 3 & 5