两者之间的区别(取自RxCookbook on GitHub):
public static IObservable<TProperty> OnPropertyChanges<T, TProperty>(this T source, Expression<Func<T, TProperty>> property)
where T : INotifyPropertyChanged
{
return Observable.Create<TProperty>(o=>
{
var propertyName = property.GetPropertyInfo().Name;
var propertySelector = property.Compile();
return Observable.FromEventPattern<PropertyChangedEventHandler, PropertyChangedEventArgs>(
handler => handler.Invoke,
h => source.PropertyChanged += h,
h => source.PropertyChanged -= h)
.Where(e => e.EventArgs.PropertyName == propertyName)
.Select(e => propertySelector(source))
.Subscribe(o);
});
}
这(由我自己写):
public static IObservable<TProperty> OnPropertyChanges<T, TProperty>(this T source, Expression<Func<T, TProperty>> property)
where T : INotifyPropertyChanged
{
var propertyName = property.GetPropertyInfo().Name;
var propertySelector = property.Compile();
return Observable.FromEventPattern<PropertyChangedEventHandler, PropertyChangedEventArgs>(
handler => handler.Invoke,
h => source.PropertyChanged += h,
h => source.PropertyChanged -= h)
.Where(e => e.EventArgs.PropertyName == propertyName)
.Select(e => propertySelector(source));
}
我认为在第二个代码块中,propertyName
和propertySelector
会在调用OnPropertyChanges
时进行求值,而在第一个代码块中,每次有人订阅时都会对这些变量求值可观察的。但是,我无法弄清楚是否/为什么第一个块比第二个块更可取,以及为什么第一个块的作者决定使用Observable.Create
。
答案 0 :(得分:0)
第一段代码作者的答案:
我对此的立场是,调用返回IObservable的方法应该什么都不做。对该返回值的订阅应调用任何副作用或处理。 如果需要在众多订阅之间分摊订阅成本,则应应用Rx中的各种多播选项。 在这种特定情况下,该论点是微弱的,但是随后使模式变得混乱,并为其他方法无需订阅即可“工作”打开了大门。我认为这是一个非常常见的错误,是造成竞争状况和资源泄漏的原因(请考虑打开连接,启动计时器等)