【问题标题】:Coverity, Enumerable.Where(this ...), and IDisposableCoverity、Enumerable.Where(this ...) 和 IDisposable
【发布时间】:2011-12-01 22:28:01
【问题描述】:

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

【问题讨论】:

  • foreach 循环会自动代表您调用 Dispose;如果代码分析工具不知道这个事实,那么您可能应该使用更准确的代码分析工具。您可以考虑将其作为错误报告给工具的维护者。
  • 这正是我的想法,但与其固执己见,我认为我应该向社区提问。
  • 或者,您应该等待生产该分析工具的人聘请 Eric Lippert 来重写他们的东西。 Coverity 中似乎不再存在此问题。

标签: c# .net linq ienumerable idisposable


【解决方案1】:

不,您不需要自己处理它。请注意,您可以在不需要 LINQ 的情况下演示此类事情。在这种情况下,我相信WhereListIterator&lt;T&gt; 实际上是一个手写类,但迭代器块显示类似的东西:

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&lt;T&gt;,还实现了IEnumerator&lt;T&gt; 作为优化——可迭代对象也充当迭代器,在通常情况下您只迭代一次。 foreach 循环将隐式处理 IEnumerator&lt;T&gt;,并且您不需要 处理它,除非您仍然进行迭代。

基本上,你在这里很好 - 虽然很遗憾 Coverity 警告你。 (老实说,我自己没有使用过 Coverity - 我不知道您是否可以在这里调整它的行为。)

【讨论】:

    【解决方案2】:

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

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

    那么你应该调用 Dispose 方法

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-01-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多