我有一个包装器类要处理,它返回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构造函数?我需要这个新类对应所有的ListOOP原则。
我不需要像这样在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,但这是完全不同的事情,可能会导致设计更改。
更新:
以下是DeferredResultCollectionEnumerableWrapper的外观:
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/

10-12 00:01