【发布时间】:2018-07-11 05:51:00
【问题描述】:
我在 .net 4 上的 Rx 框架中迈出了第一步。
我正在尝试观察像List<int> 或Dictionary<x,x> 这样的集合。
当一个项目被添加到集合中时,它将在控制台中写入ToString()。
有什么想法吗?或一些代码示例 谢谢
【问题讨论】:
标签: c# system.reactive
我在 .net 4 上的 Rx 框架中迈出了第一步。
我正在尝试观察像List<int> 或Dictionary<x,x> 这样的集合。
当一个项目被添加到集合中时,它将在控制台中写入ToString()。
有什么想法吗?或一些代码示例 谢谢
【问题讨论】:
标签: c# system.reactive
List<T> 和 Dictionary<TKey, TValue> 是不可观察的(它们在发生变化时不会引发事件),因此 Rx 没有什么可以挂钩的。
对于List,您可以使用ObservableCollection<T>,但您需要包装其事件以从Rx 使用它。下面是一个使用扩展方法的例子:
public static class ObservableCollectionExtensions
{
public static IObservable<IEvent<NotifyCollectionChangedEventArgs>>
GetObservableChanges<T>(this ObservableCollection<T> collection)
{
return Observable.FromEvent<
NotifyCollectionChangedEventHandler, NotifyCollectionChangedArgs>(
h => new NotifyCollectionChangedEventHandler(h),
h => collection.CollectionChanged += h,
h => collection.CollectionChanged -= h
);
}
public static IObservable<T> GetObservableAddedValues<T>(
this ObservableCollection<T> collection)
{
return collection.GetObservableChanges()
.Where(evnt => evnt.EventArgs.Action == NotifyCollectionChangedAction.Add)
.SelectMany(evnt => evnt.EventArgs.NewItems.Cast<T>());
}
}
我添加了一个额外的助手,它只将新添加的项目公开为IObservable<T>,您可以像这样使用它:
ObservableCollection<int> collection =
new ObservableCollection<int>(new int[] { 1, 2, 3 });
collection.GetObservableAddedValues().Subscribe(
i => Console.WriteLine("{0} was added", i)
);
框架中没有可观察的字典,尽管ObservableDictionary codeplex project 似乎填补了这个空白,我相信它可以以类似的方式包装。
【讨论】:
使用来自ReactiveUI的ReactiveCollection:
var c = new ReactiveCollection<int>();
c.Changed.Subscribe(x => Console.Writeln(x.Value);
c.Add(1);
【讨论】:
对于那些没有使用IEvent接口的选项,可以使用FromEventPattern代替:
public static class ObservableCollectionExtensions
{
public static IObservable<EventPattern<NotifyCollectionChangedEventArgs>>
GetObservableChanges<T>(this ObservableCollection<T> collection)
{
return Observable.FromEventPattern<
NotifyCollectionChangedEventHandler, NotifyCollectionChangedEventArgs>(
h => collection.CollectionChanged += h,
h => collection.CollectionChanged -= h
);
}
public static IObservable<T> GetObservableAddedValues<T>(
this ObservableCollection<T> collection)
{
return collection.GetObservableChanges()
.Where(evnt => evnt.EventArgs.Action == NotifyCollectionChangedAction.Add)
.SelectMany(evnt => evnt.EventArgs.NewItems.Cast<T>());
}
}
【讨论】: