c# - 如何使用 LINQ 处理 IDisposable 的序列?

标签 c# linq ienumerable dispose idisposable

调用 Dispose() 的最佳方法是什么?关于序列的元素?

假设有这样的东西:

IEnumerable<string> locations = ...
var streams = locations.Select ( a => new FileStream ( a , FileMode.Open ) );
var notEmptyStreams = streams.Where ( a => a.Length > 0 );
//from this point on only `notEmptyStreams` will be used/visible
var firstBytes = notEmptyStreams.Select ( a => a.ReadByte () );
var average = firstBytes.Average ();

你如何处置FileStream实例(一旦不再需要),同时保持简洁代码?


澄清一下:这不是一段实际的代码,这些行是一组类中的方法,并且 FileStream类型也只是一个例子。


正在按照以下方式做某事:

public static IEnumerable<TSource> Where<TSource> (
            this IEnumerable<TSource> source ,
            Func<TSource , bool> predicate
        )
        where TSource : IDisposable {
    foreach ( var item in source ) {
        if ( predicate ( item ) ) {
            yield return item;
        }
        else {
            item.Dispose ();
        }
    }
}

可能是个好主意?


或者:您是否总是解决关于 IEnumerable<IDisposable> 的非常具体的场景?没有试图概括?是因为有它是一种不典型的情况吗?您是否首先围绕拥有它进行设计?如果是,怎么办?

最佳答案

我会写一个方法,比如 AsDisposableCollection,它返回一个包装好的 IEnumerable,它也实现了 IDisposable,这样你就可以使用通常的使用 模式。这需要做更多的工作(方法的实现),但您只需要一次,然后就可以很好地使用该方法(根据需要经常使用):

using(var streams = locations.Select(a => new FileStream(a, FileMode.Open))
                             .AsDisposableCollection()) {
  // ...
} 

实现大致如下所示(不完整 - 只是为了展示想法):

class DisposableCollection<T> : IDisposable, IEnumerable<T> 
                                where T : IDisposable {
  IEnumerable<T> en; // Wrapped enumerable
  List<T> garbage;   // To keep generated objects

  public DisposableCollection(IEnumerable<T> en) {
    this.en = en;
    this.garbage = new List<T>();
  }
  // Enumerates over all the elements and stores generated
  // elements in a list of garbage (to be disposed)
  public IEnumerator<T> GetEnumerator() { 
    foreach(var o in en) { 
      garbage.Add(o);
      yield return o;
    }
  }
  // Dispose all elements that were generated so far...
  public Dispose() {
    foreach(var o in garbage) o.Dispose();
  }
}

关于c# - 如何使用 LINQ 处理 IDisposable 的序列?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3693052/

相关文章:

c# - 如何从 C# 中的列表中选择第二高的值?

c# - Sharepoint 客户端对象模型设置 ModifiedBy 字段

c# - 以某种方式排序的日期列表

c# - 在 IEnumerable View 中编辑数据(订单行的项目)

c# - 如何实现通用 IEnumerable 或 IDictionary 以避免 CA1006?

c# - 使用 Newtonsoft JSON.Net 在反序列化之前合并源 JSON

c# - 获取windows用户的登录和注销日志

c# - 从列表中指定索引处删除元素的有效方法

c# - 与 MIN 等效的 LINQ 是什么?

C#:如何实现 IOrderedEnumerable<T>