【问题标题】:Integration with event where the delegate has more than one argument and there are no EventArgs与委托具有多个参数且没有 EventArgs 的事件集成
【发布时间】:2016-08-03 20:18:17
【问题描述】:

似乎没有FromEventFromEventPattern 方法的重载将转换为IObservable<T> 类型为TDelegate 的事件,仅在有多个参数且没有EventArgs 的情况下.

例如看来我们无法将以下内容转换为 observables。

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;

【问题讨论】:

    标签: c# system.reactive


    【解决方案1】:

    使用类测试器

    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&lt;TDelegate, TEventArgs&gt; (Func&lt;Action&lt;TEventArgs&gt;, TDelegate&gt;, Action&lt;TDelegate&gt;, Action&lt;TDelegate&gt;) 与转换功能一起使用,如下所示:

    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 有一个很好的参考。

    【讨论】:

    • 非常感谢和抱歉迟到的回复。从那以后我就没有机会接触 Rx 了。我很快就会重新开始研究它。
    • 我知道过载并且过去曾使用它进行转换。可能我的想法还不够充分,无法看到它在这种情况下也能奏效。
    【解决方案2】:

    我必须说我在public event Func&lt;string, int&gt; SomethingElseHappened; 事件中遇到了困难,但这是一个奇怪的事件,事件实际上返回了一个值。

    但是,使用public event Action&lt;int, int&gt; SomethingHappened;,使用FromEvent 非常简单。

    鉴于这个类:

    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);
    

    ...给我们:

    发生了什么事:3 & 5

    【讨论】:

    • 谢谢,谢谢,很抱歉回复晚了。
    • 对不起,这两个答案都很棒。我不知道该选哪一个作为正确的,所以纯粹随机选择,因为另一个也有链接。不过,我喜欢你的回答。
    • @Enigmativ
    • @AdamDiament - 我现在不在。一周后联系我,我会看看。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-16
    • 2011-08-15
    • 1970-01-01
    相关资源
    最近更新 更多