Coverity、Enumerable.Where(this ...) 和 IDisposable
因此,代码分析告诉我 Enumarble.Where(this ...)
正在返回 WhereListIterator
的实例,它(看起来是)内部类型在实现 IDisposable 的 .NET 框架内。
Coverity 不喜欢 IDisposable
未被处置,因此建议我处置所述实例。显然,如果不进行一些类型检查,我就无法处置该实例,因为 Enumerable.Where(this ...)
据说返回 IEnumerable
,这确实不是来自 IDisposable
的 ihnerit。
我的问题是:.NET 是否期望我处理 WhereListIterator
,或者迭代器自行处理(例如,在每次枚举之后)。如果我不希望处置它,那么为什么要实现该接口?这引出了第三个稍微不相关的问题:如果显式实现了 IDisposable,Coverity(代码分析)是否仍然认为我应该处置它?
代码示例:
var myList = new List<int>{ 1, 2, 3, 4 };
var evenNumbers = myList.Where(x => x % 2 == 0);
foreach(var number in evenNumbers)
{
Console.WriteLine(number);
}
if(evenNumbers is IDisposable)
{
((IDisposable)evenNumbers).Dispose(); // This line will be executed
}
So code analysis is telling me that Enumarble.Where(this ...)
is returning an instance of WhereListIterator<T>
, which is (looks to be) an internal type within the .NET framework that implements IDisposable
.
Coverity doesn't like IDisposable
's to go un-disposed, and is therefore suggesting I dispose of said instance. Obviously I can't dispose of the instance without doing some type checking, as Enumerable.Where(this ...)
is said to return IEnumerable<T>
, which does not ihnerit from IDisposable
.
My question is this: Does .NET expect me to dispose of the WhereListIterator<T>
, or does the iterator dispose of itself (say, after each enumeration). If I'm not expected to dispose of it, then why is the interface implemented? This leads me to a third, slightly unrelated question: If IDisposable
was implemented explicitly, would Coverity (code analysis) still think that I should dispose of it?
Code Example:
var myList = new List<int>{ 1, 2, 3, 4 };
var evenNumbers = myList.Where(x => x % 2 == 0);
foreach(var number in evenNumbers)
{
Console.WriteLine(number);
}
if(evenNumbers is IDisposable)
{
((IDisposable)evenNumbers).Dispose(); // This line will be executed
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
不,您不需要自己处理它。请注意,您无需使用 LINQ 即可演示此类事情。在这种情况下,我相信
WhereListIterator
实际上是一个手写的类,但迭代器块显示了类似的东西:它确实实现了
IDisposable
因为它不仅实现了IEnumerable
而且IEnumerator
作为一种优化 - 可迭代也充当迭代器,在常见情况下,您只需要迭代一次。foreach
循环将隐式处置IEnumerator
,除非您进行迭代,否则您不需要处置它。基本上,你在这里没问题 - 尽管遗憾的是 Coverity 正在警告你这一点。 (老实说,我自己没有使用过 Coverity - 我不知道是否可以做一些事情来调整它的行为。)
No, you don't need to dispose of it yourself. Note that you can demonstrate this sort of thing without any need for LINQ. In this case I believe
WhereListIterator<T>
is actually a hand-written class, but an iterator block shows something similar:It really implements
IDisposable
because it implements not justIEnumerable<T>
but alsoIEnumerator<T>
as an optimization - the iterable acts as the iterator as well, in the common case where you only iterate once. Aforeach
loop will implicitly dispose of anIEnumerator<T>
, and you don't need to dispose of it unless you iterate anyway.Basically, you're fine here - although it's a pity that Coverity is warning you about it. (I haven't used Coverity myself, to be honest - I don't know if there's something you can do to tweak its behaviour here.)
如果您不使用 foreach 循环并使用旧的迭代方式
,那么您应该调用 Dispose 方法
if you are not using the foreach loop and using the old way to iterate
then you should call the Dispose method