【发布时间】:2015-11-12 22:35:11
【问题描述】:
在序列元素上调用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> 的非常具体的场景?是不是因为拥有它是一种不典型的情况?您是否首先围绕拥有它进行设计?如果有,怎么做?
【问题讨论】:
-
我不喜欢这个问题的一点是,如果没有您试图实现的具体场景,答案中的所有努力都可能完全失败。这引发了一次有趣的讨论,但可能远未找到真正的解决方案。
-
针对特定场景的专门解决方案很可能是微不足道的,正如迄今为止的答案所示。如果有更通用的方法来处理 IEnumerable
,我很感兴趣。我认为,围绕 IDisposable 创建一个 monad 是朝着这个方向迈出的一步。 -
我认为您的方法示例不是一个好主意。 LINQ 方法不应该对枚举值产生副作用,而您的方法有一个非常严重的副作用。
标签: c# linq ienumerable dispose idisposable