我一直在努力通过跟随Bart De Smetts MinLinq和Jon Skeets' Reimplementing'更加深入地了解Rx。我已经建立了一个很好的理解但是......
以下面的代码为例
var onePerSecond = Observable.Interval(TimeSpan.FromSeconds(1));
var evenNums = onePerSecond.Where(x => x % 2 == 0);
evenNums.Subscribe(Console.WriteLine);
从equivelant IEnumerable 的角度来看,我理解MoveNext / Current的数据流,以及来自Skeets先生的数据流。博客如何使用foreach而不是IEnumerable来实现Where方法'这个'扩展方法的参数。
但是对于IObservable的Where方法,它是否包含实现IObserver接口(或lambda equivelant)的代码,因此有效地观察来自onePerSecond对象的所有通知,然后返回一个IObservable只包含谓词发现为真的值?
非常欢迎任何帮助和想法,非常感谢
詹姆斯
答案 0 :(得分:3)
通过查看ILSpy的源代码,很容易看出究竟是如何实现的。它返回一个新的observable,它根据你传递的谓词过滤项目:
public static IObservable<TSource> Where<TSource>(this IObservable<TSource> source, Func<TSource, bool> predicate)
{
if (source == null)
{
throw new ArgumentNullException("source");
}
if (predicate == null)
{
throw new ArgumentNullException("predicate");
}
return new AnonymousObservable<TSource>((IObserver<TSource> observer) => source.Subscribe(delegate(TSource x)
{
bool flag;
try
{
flag = predicate(x);
}
catch (Exception error)
{
observer.OnError(error);
return;
}
if (flag)
{
observer.OnNext(x);
}
}
, new Action<Exception>(observer.OnError), new Action(observer.OnCompleted)));
}
答案 1 :(得分:1)
以下是一些玩具示例,以了解它的工作原理:
https://github.com/ScottWeinstein/Rx-Demo/tree/master/ImplementWhereDemo
public class WhereObservableLessPedantic<T> : IObservable<T>
{
private Func<T, bool> _pred;
private IObservable<T> _stream;
public WhereObservableLessPedantic(IObservable<T> stream, Func<T, bool> pred)
{
_pred = pred;
_stream = stream;
}
public IDisposable Subscribe(IObserver<T> downStreamObserver)
{
Action<T> onNext = nextVal =>
{
if (_pred(nextVal))
downStreamObserver.OnNext(nextVal);
};
return _stream.Subscribe(onNext);
}
}
public class WhereObserverPedantic<T> : IObserver<T>
{
private IObserver<T> _downStreamObserver;
private Func<T, bool> _pred;
public WhereObserverPedantic(IObserver<T> downStreamObserver, Func<T, bool> pred)
{
_pred = pred;
_downStreamObserver = downStreamObserver;
}
public void OnNext(T value)
{
if (_pred(value))
{
_downStreamObserver.OnNext(value);
}
}
public void OnCompleted() { }
public void OnError(Exception error) { }
}