3

IObserver の次の C# 拡張メソッドがあります。中間サブジェクトを使用して、LINQ 式を先頭に置くことができます。

/// <summary>
/// Given an IObserver we may wish to build a new IObserver that has LINQ
/// combinators at it's head.
///
///     observer = observer.Wrap(observable=>observable.Where(k=>k>0));
///
/// </summary>
public static IObserver<U>
 Wrap<T,U>
 ( this IObserver<T> This
 , Func<IObservable<U>, IObservable<T>> fn 
 )
{
    var s = new Subject<U>();
    fn(s).Subscribe(This);
    return s;
}

ただし、メソッドを使用すると

    [Fact]
    public void WrapShouldWrapObservers()
    {
        var b = new List<int>() { 0, 1, 2,3,4,5 };
        var s = new Subject<int>();
        var c = new List<int>();

        var obs = s.Wrap(observable => observable.Where(k => k > 3));

        s.Subscribe(v => c.Add(v));

        b.ToObservable().Subscribe(obs);
        c.Should().BeEquivalentTo(4, 5);

    }

エラーが表示されます

Error   2   The type arguments for method

ReactiveUI.Ext.IObservableMixins.Wrap<T,U>
( System.IObserver<T>
, System.Func<System.IObservable<U>,System.IObservable<T>>
)

cannot be inferred from the usage. Try specifying the type arguments
explicitly. 

型引数を明示的に入力すると、機能します。

    var obs = s.Wrap<int,int>(observable => observable.Where(k => k > 3));

ただし、検査から、型引数を省略してもあいまいさはありません。ここで何が問題なのですか?

- - - - - -答え - - - - - -

テストケースを変更してタイプを適切に実行すると、問題が何であるかが明らかになります

    [Fact]
    public void WrapShouldWrapObservers()
    {
        var b = new List<int>() { 0, 1, 2,3,4,5 };
        var s = new Subject<string>();
        var c = new List<string>();

        var obs2 = s.Wrap<int,string>(observable => observable.Where(k => k > 3).Select(k=>k.ToString()));

        s.Subscribe(v => c.Add(v));

        b.ToObservable().Subscribe(obs2);
        c.Should().BeEquivalentTo("4", "5");
    }

observableラムダの最初の引数がどうあるべきかを知ることはできません。ラムダは IObservable を返さなければなりませんが、これを達成するために無限の数のオブザーバブル型があります。

4

2 に答える 2