从 IObservable 列表创建一个 IObservableList
Create a IObservableList from a list of IObservable
我正在寻找一个实现 IObservable<IReadOnlyList<T>>
和 IList<IObservable<T>>
.
的反应对象
就是这样,我希望能够写:
var list = new MyReactiveList<int>();
var item = new Subject<int>();
list.Subscribe(values => Console.WriteLine($"[{string.Join(", ", values)}]"));
list.Add(item);
item.OnNext(1); // Will print out [1]
首先,您在问题中发布的代码无法编译。我已尽我所能修复它:
var list = new MyReactiveList<int>();
var item = new Subject<int>();
list.Subscribe(values => Console.WriteLine($"[{string.Join(", ", values)}]"));
list.Add(item);
item.OnNext(1); // Will print out [1]
现在练习只是为了实现class MyReactiveList<T> : IObservable<IReadOnlyList<T>>, IList<IObservable<T>>
。这很简单,但唯一的问题是以某种方式将可变 List<IObservable<T>>
转换为 IObservable<IReadOnlyList<T>>
,以便当列表更改时可观察对象会自行更新。
这里是:
public class MyReactiveList<T> : IObservable<IReadOnlyList<T>>, IList<IObservable<T>>
{
private List<IObservable<T>> _list = new List<IObservable<T>>();
private Subject<Unit> _update = new Subject<Unit>();
public IDisposable Subscribe(IObserver<IReadOnlyList<T>> observer) =>
_update
.Select(_ => _list.CombineLatest().Select(x => new ReadOnlyList<T>(x)))
.Switch()
.Subscribe(observer);
public IObservable<T> this[int index]
{
get => _list[index];
set
{
_list[index] = value;
_update.OnNext(Unit.Default);
}
}
public int Count => _list.Count;
public bool IsReadOnly => false;
public void Add(IObservable<T> item)
{
_list.Add(item);
_update.OnNext(Unit.Default);
}
public void Clear()
{
_list.Clear();
_update.OnNext(Unit.Default);
}
public bool Contains(IObservable<T> item) => _list.Contains(item);
public void CopyTo(IObservable<T>[] array, int arrayIndex)
{
_list.CopyTo(array, arrayIndex);
}
public IEnumerator<IObservable<T>> GetEnumerator() => _list.GetEnumerator();
public int IndexOf(IObservable<T> item) => _list.IndexOf(item);
public void Insert(int index, IObservable<T> item)
{
_list.Insert(index, item);
_update.OnNext(Unit.Default);
}
public bool Remove(IObservable<T> item)
{
var removed = _list.Remove(item);
_update.OnNext(Unit.Default);
return removed;
}
public void RemoveAt(int index)
{
_list.RemoveAt(index);
_update.OnNext(Unit.Default);
}
IEnumerator IEnumerable.GetEnumerator() => _list.GetEnumerator();
}
public class ReadOnlyList<T> : IReadOnlyList<T>
{
public ReadOnlyList(IEnumerable<T> items) { _list.AddRange(items); }
private List<T> _list = new List<T>();
public T this[int index] => _list[index];
public int Count => _list.Count;
public IEnumerator<T> GetEnumerator() => _list.GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => _list.GetEnumerator();
}
注意:实现自己的可观察对象并不是一个好主意 - 很容易弄错它们并创建不能很好地处理并发的代码。
我正在寻找一个实现 IObservable<IReadOnlyList<T>>
和 IList<IObservable<T>>
.
就是这样,我希望能够写:
var list = new MyReactiveList<int>();
var item = new Subject<int>();
list.Subscribe(values => Console.WriteLine($"[{string.Join(", ", values)}]"));
list.Add(item);
item.OnNext(1); // Will print out [1]
首先,您在问题中发布的代码无法编译。我已尽我所能修复它:
var list = new MyReactiveList<int>();
var item = new Subject<int>();
list.Subscribe(values => Console.WriteLine($"[{string.Join(", ", values)}]"));
list.Add(item);
item.OnNext(1); // Will print out [1]
现在练习只是为了实现class MyReactiveList<T> : IObservable<IReadOnlyList<T>>, IList<IObservable<T>>
。这很简单,但唯一的问题是以某种方式将可变 List<IObservable<T>>
转换为 IObservable<IReadOnlyList<T>>
,以便当列表更改时可观察对象会自行更新。
这里是:
public class MyReactiveList<T> : IObservable<IReadOnlyList<T>>, IList<IObservable<T>>
{
private List<IObservable<T>> _list = new List<IObservable<T>>();
private Subject<Unit> _update = new Subject<Unit>();
public IDisposable Subscribe(IObserver<IReadOnlyList<T>> observer) =>
_update
.Select(_ => _list.CombineLatest().Select(x => new ReadOnlyList<T>(x)))
.Switch()
.Subscribe(observer);
public IObservable<T> this[int index]
{
get => _list[index];
set
{
_list[index] = value;
_update.OnNext(Unit.Default);
}
}
public int Count => _list.Count;
public bool IsReadOnly => false;
public void Add(IObservable<T> item)
{
_list.Add(item);
_update.OnNext(Unit.Default);
}
public void Clear()
{
_list.Clear();
_update.OnNext(Unit.Default);
}
public bool Contains(IObservable<T> item) => _list.Contains(item);
public void CopyTo(IObservable<T>[] array, int arrayIndex)
{
_list.CopyTo(array, arrayIndex);
}
public IEnumerator<IObservable<T>> GetEnumerator() => _list.GetEnumerator();
public int IndexOf(IObservable<T> item) => _list.IndexOf(item);
public void Insert(int index, IObservable<T> item)
{
_list.Insert(index, item);
_update.OnNext(Unit.Default);
}
public bool Remove(IObservable<T> item)
{
var removed = _list.Remove(item);
_update.OnNext(Unit.Default);
return removed;
}
public void RemoveAt(int index)
{
_list.RemoveAt(index);
_update.OnNext(Unit.Default);
}
IEnumerator IEnumerable.GetEnumerator() => _list.GetEnumerator();
}
public class ReadOnlyList<T> : IReadOnlyList<T>
{
public ReadOnlyList(IEnumerable<T> items) { _list.AddRange(items); }
private List<T> _list = new List<T>();
public T this[int index] => _list[index];
public int Count => _list.Count;
public IEnumerator<T> GetEnumerator() => _list.GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => _list.GetEnumerator();
}
注意:实现自己的可观察对象并不是一个好主意 - 很容易弄错它们并创建不能很好地处理并发的代码。