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

cwh*_*ris 6 .net c# linq ienumerable idisposable

所以代码分析告诉我,它Enumarble.Where(this ...)正在返回一个实例WhereListIterator<T>,它实现了(看起来是)实现的.NET框架中的内部类型IDisposable.

Coverity不喜欢IDisposable不被处置,因此建议我处理所述实例.显然,我不能在没有进行某种类型检查的情况下处理该实例,就像Enumerable.Where(this ...)据说返回一样IEnumerable<T>,这并不是真的IDisposable.

我的问题是:.NET是否希望我处理它WhereListIterator<T>,或者迭代器处理它自己(比如,在每次枚举之后).如果我没有被要求处理它,那么为什么接口实现?这引出了我第三个略有不相关的问题:如果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
}
Run Code Online (Sandbox Code Playgroud)

Jon*_*eet 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

这真的实现了IDisposable,因为它实现不仅仅是IEnumerable<T>IEnumerator<T>作为优化-可迭代充当迭代器,以及,在通常情况下,你只有一次迭代.一个foreach循环将隐式处理一个IEnumerator<T>,你不需要处理它,除非你无论如何迭代.

基本上,你在这里很好 - 虽然很可惜Coverity正在警告你.(我自己也没有使用Coverity,说实话 - 我不知道你能做些什么来调整它的行为.)


Sle*_*idi 5

如果您没有使用foreach循环并使用旧方法进行迭代

var v = new List<int>() { 1,2,3};
var enumerator = v.GetEnumerator();
while (enumerator.MoveNext())
{

    Console.WriteLine(enumerator.Current);
}
Run Code Online (Sandbox Code Playgroud)

那么你应该调用Dispose方法