调用 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/