因此代码分析告诉我Enumarble.Where(this ...)
正在返回WhereListIterator<T>
的实例,它是(看起来是).NET框架中实现IDisposable
的内部类型。< / p>
Coverity不喜欢IDisposable
没有处置,因此建议我处理所述实例。显然,我不能在不进行某些类型检查的情况下处理实例,因为Enumerable.Where(this ...)
被称为返回IEnumerable<T>
,而IDisposable
并不是{i}。
我的问题是:.NET是否希望我处理WhereListIterator<T>
,或者迭代器是否自行处理(例如,在每次枚举后)。如果我没有被要求处理它,那么为什么接口实现?这引出了我第三个稍微不相关的问题:如果IDisposable
被明确实施,那么Coverity(代码分析)是否仍然认为我应该处理它?</ p>
代码示例:
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
}
答案 0 :(得分:12)
不,你不需要自己处理它。请注意,您可以在不需要LINQ的情况下演示此类事情。在这种情况下,我相信WhereListIterator<T>
实际上是一个手写的类,但迭代器块显示类似的东西:
using System;
using System.Collections.Generic;
public class Program
{
static void Main(string[] args)
{
var empty = Empty();
Console.WriteLine(empty is IDisposable); // Prints True
}
static IEnumerable<string> Empty()
{
yield break;
}
}
它确实实现了IDisposable
,因为它不仅实现IEnumerable<T>
而且实现IEnumerator<T>
作为优化 - 迭代也充当迭代器,在常见的情况下,您只迭代一次。 foreach
循环将隐式处理IEnumerator<T>
,并且除非您无论如何迭代,否则 无需处理它。
基本上,你在这里很好 - 虽然很可惜Coverity会警告你。 (我自己也没有使用过Coverity,说实话 - 我不知道你能做些什么来调整它的行为。)
答案 1 :(得分:5)
如果您没有使用foreach循环并使用旧方法进行迭代
var v = new List<int>() { 1,2,3};
var enumerator = v.GetEnumerator();
while (enumerator.MoveNext())
{
Console.WriteLine(enumerator.Current);
}
然后你应该调用Dispose方法