【问题标题】:Is this a bug in resharper?这是resharper中的错误吗?
【发布时间】:2015-06-18 12:06:36
【问题描述】:

我这里有一些 Resharper 曲线。

他们告诉我,我有一个可能的多个 IEnumerable 枚举。但是,您可以看到这是不正确的。 final 明确声明为列表 (List<Point2D>),pointTangents 之前声明为 List<PointVector2D>

知道为什么 Resharper 会告诉我这个吗?

编辑实验以查看是否可以使用更简单的代码进行复制

正如您在下面看到的那样,即使 Bar 被声明为采用 IEnumerable 作为参数,也没有曲线和警告。

【问题讨论】:

  • pointTangents 是什么类型?这是从哪里来的?
  • 问题说它是一个列表。准确地说是 List。不是 IEnumerable 这就是为什么 resharper 不应该给出这个警告。
  • 显示更多您的代码 - 可以作为 IEnumerable 传递吗?
  • 为什么不自己计算第一个/最后一个?
  • 您将鼠标移到 2 个突出显示的类型上,它们都是该范围内的 List?如果是,看起来像一个 Resharper 错误。

标签: c# resharper ienumerable


【解决方案1】:

看起来很像RSRP-429474 False-positive warning for possible multiple enumeration

我有这个代码:

List<string> duplicateLabelsList = allResourcesLookup.SelectMany(x => x).Select(x => x.LoaderOptions.Label).Duplicates<string, string>().ToList(); ; 
if (duplicateLabelsList.Any()) 
throw new DuplicateResourceLoaderLabelsException(duplicateLabelsList);

对于duplicateLabelsList 的两种用法,我都收到了警告 可能的多个枚举,尽管我已经调用了 ToList 和 因此不应该有多重枚举。

(当前)有一个 9.2 的修复版本,(当前)尚未发布。

【讨论】:

    【解决方案2】:

    IEnumberable&lt;TSource&gt;类型定义了扩展方法public static TSource Last&lt;TSource&gt;(this IEnumerable&lt;TSource&gt; source);

    如果看一下Last&lt;TSource&gt;的实现:

    public static TSource Last<TSource>(this IEnumerable<TSource> source)
    {
        if (source == null) throw Error.ArgumentNull("source");
        IList<TSource> list = source as IList<TSource>;
        if (list != null)
        {
             int count = list.Count;
             if (count > 0) return list[count - 1];
        }
        else
        {
             using (IEnumerator<TSource> e = source.GetEnumerator()) 
             {
                  if (e.MoveNext())
                  {
                        TSource result;
    
                        do
                        {
                           result = e.Current;
                        } while (e.MoveNext());
    
                        return result;
                  }
             }
        }
        throw Error.NoElements();
    }
    

    很明显,如果source 实现了IList,则不会枚举source,因此您认为这是Resharper 中的“错误”是正确的。

    我认为它更像是误报,可能是因为 Resharper 没有一般的方法知道Last() 的实现避免了不必要的枚举。它可能决定根据 Last&lt;TSource&gt; 是为类型化 IEnumerable&lt;T&gt; 对象定义的事实来标记潜在的多重枚举。

    【讨论】:

    • 我做了一个测试。看看屏幕截图。 Resharper 能够理解差异。
    • @bradgonesurfing 您是否尝试过查看 Resharper 在传递IEnumerable 时是否标记了相同的代码?我不认为该代码与您的原始问题完全相同。
    • 是的。我尝试传递一个 IEnumerable 并对其进行标记。用列表交换它,它不会标记它。
    • 它会标记多个枚举,因为有个枚举。关键是 Resharper 通常不会标记 List 的多个枚举,因为它知道其中的枚举不涉及诸如发出数据库查询之类的昂贵操作。 AFAIK 它只查看可枚举的类型,是否有多个枚举,以及是否需要考虑注释/属性。 tl;dr 有多个枚举,但 Resharper 通常在枚举类型为 List 时忽略这些。
    • @StephenKennedy 但这就是重点:FirstLast 枚举。查看实现,它只是在传递的对象实现IList时返回list[0]list[count - 1]
    猜你喜欢
    • 2011-02-05
    • 1970-01-01
    • 2013-05-04
    • 2011-09-28
    • 2017-07-23
    • 2012-09-15
    • 2017-03-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多