Search code examples
c#reactive-programmingsystem.reactiverx.net

Reactive Merge Observables C#


I am trying to learn how to work with "System.Reactive" in my C# application. Now I am playing with the merge operations, but perhaps I misunderstood something.

I have the following test class with two events (different event args)

public class FirstArgs
{
    public FirstArgs(double val)
    {
        Value = val;
    }
    double Value { get; }
}

public class SecondArgs
{
    public SecondArgs(int val)
    {
        Value = val;
    }
    int Value { get; }
}

public class TestClass
{
    private double _firstValue;
    private int _secondValue;

    public EventHandler<FirstArgs> FirstChanged;
    public EventHandler<SecondArgs> SecondChanged;

    public double FirstValue 
    {
        get => _firstValue; 
        private set
        {
            if(_firstValue != value) 
            {
                _firstValue = value;
                FirstChanged?.Invoke(this, new FirstArgs(value));
            }
        }
    }
    public int SecondValue
    {
        get => _secondValue;
        private set
        {
            if (_secondValue != value)
            {
                _secondValue = value;
                SecondChanged?.Invoke(this, new SecondArgs(value));
            }
        }
    }
}

Now I want to observe both events and when one of the event fires I want to call a dedicated method. Therefore I tried the following:

            TestClass testClass = new TestClass();
        var first = Observable.FromEventPattern<EventHandler<FirstArgs>, FirstArgs>(
            h => testClass.FirstChanged += h,
            h => testClass.FirstChanged -= h);
        var second = Observable.FromEventPattern<EventHandler<SecondArgs>, SecondArgs>(
            h => testClass.SecondChanged += h,
            h => testClass.SecondChanged -= h);

        Observable.Merge(first, second).
            Sample(TimeSpan.FromMilliseconds(30)).
            Subscribe(_ => Debug.WriteLine("Do Something"));

But the merge doesn't work because of the different event arguments. So how can I observe two different events and call a dedicated method if one of them fires (in addition with the sampling)?


Solution

  • As C# doesn't have typescript-style union types, you can't mix types in your observable. I would select both of your observables into a common type and then merge that.

    Something like:

           var first = Observable.FromEventPattern<EventHandler<FirstArgs>, FirstArgs>(
                h => testClass.FirstChanged += h,
                h => testClass.FirstChanged -= h)
            .Select(first => Unit.Default);
            var second = Observable.FromEventPattern<EventHandler<SecondArgs>, SecondArgs>(
                h => testClass.SecondChanged += h,
                h => testClass.SecondChanged -= h);
            .Select(second => Unit.Default);