Coverity,Enumerable.Where(this ...)和IDisposable

时间:2011-12-01 22:28:01

标签: c# .net linq ienumerable idisposable

因此代码分析告诉我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
}

2 个答案:

答案 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方法