我有一个包装器类要处理,它返回IAsyncCursor
我的程序可以从两个位置获取项目:
IEnumerable<TResult> GetItems()
{
List<TResult> fromA = fromA();
IEnumerable<TResult> fromB = fromB();
var result = fromA.Concat(fromB).ToList();
return result;
}
但我不想把
IEnumerable<TResult>
存储在内存中,因为它太贵了。我想将
result
的返回结果更改为返回GetItems()
,并且能够调用ResultCollection
因此,我需要将
Dispose()
和fromA()
方法的结果更改为返回fromB()
,如下所示ResultCollection<TResult> GetItems()
{
ResultCollection<TResult> fromA = fromA(); // wrap List<TResult> to ResultCollection
ResultCollection<TResult> fromB = fromB(); // return collection that I can dispose when I need
return new ResultCollection<TResult>(fromA.Concat(fromB).ToList());
}
如何将
ResultCollection
更改为存储ResultCollection
构造函数?我需要这个新类对应所有的List
和OOP
原则。我不需要像这样在
SOLID
中只有另一个构造函数public ResultCollection(IList<TResult> list)
{
_list = list;
}
最佳答案
您可以创建一个名为IDisposableEnumerable
的新接口,该接口具有以下定义:
public interface IDisposableEnumerable<T> : IEnumerable<T>, IDisposable
{
}
然后让您的
DeferredResultCollection
类实现这样的接口。然后,您应该创建这样的接口的另一个实现,它包装任何
IEnumerable<T>
。这样的类可以被称为EnumerableWrapper
,它在其Dispose
方法中什么也不做。您还需要创建另一个实现,该实现可以使用Composite Pattern将两个(或更多)对象合并在一起,这样的类可以称为
IDisposableEnumerable
。请注意,当调用非最佳异步方法时,
CompositeDisposableEnumerable
类会阻塞。您可能还想考虑使用Reactive Extensions for .NET,但这是完全不同的事情,可能会导致设计更改。
更新:
以下是
DeferredResultCollection
和EnumerableWrapper
的外观:public class EnumerableWrapper<T> : IDisposableEnumerable<T>
{
private readonly IEnumerable<T> m_Enumerable;
public EnumerableWrapper(IEnumerable<T> enumerable)
{
m_Enumerable = enumerable;
}
public void Dispose()
{
}
public IEnumerator<T> GetEnumerator()
{
return m_Enumerable.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return ((IEnumerable) m_Enumerable).GetEnumerator();
}
}
public class CompositeDisposableEnumerable<T> : IDisposableEnumerable<T>
{
private readonly IDisposableEnumerable<T>[] m_DisposableEnumerables;
public CompositeDisposableEnumerable(params IDisposableEnumerable<T>[] disposable_enumerables)
{
m_DisposableEnumerables = disposable_enumerables;
}
public IEnumerator<T> GetEnumerator()
{
foreach (var disposable_enumerable in m_DisposableEnumerables)
{
foreach (var item in disposable_enumerable)
yield return item;
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public void Dispose()
{
foreach (var disposable_enumerable in m_DisposableEnumerables)
disposable_enumerable.Dispose();
}
}
更新:
下面是一个示例用法:
public IDisposableEnumerable<T> GetItems<T>()
{
List<T> collection1 = ....;
DeferredResultCollection<T> collection2 = new DeferredResultCollection<T> (async_cursor);
return new CompositeDisposableEnumerable<T>(new EnumerableWrapper<T>(collection1), collection2);
}
从消费者的角度来看:
using(var items = GetItems<string>())
{
//do something with items
} //This will invoke `Dispose` which will be propagated finally to DeferredResultCollection.Dispose and thus to IAsyncCursor.Dispose
关于c# - 如何添加不会破坏OOP原理的新构造函数?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/33856185/