【问题标题】:Statically detect type mismatches in foreach statement静态检测 foreach 语句中的类型不匹配
【发布时间】:2016-10-17 20:38:27
【问题描述】:

我有一个大型 C# 代码库,我正试图在其中重构和清理其他人纠结的代码。我最近偶然发现了这样一个块:

List<Bar> bars = ... ;

...

foreach (Foo foo in bars) { ... }

...

public class Bar
{
    ...

    public static explicit operator Foo() { ... }
}

这种类型不匹配是个问题。而且,正如您所料,代码并没有真正起作用:这是一个隐藏了很长时间的错误。

但是,代码是合法的。 Visual Studio 2013 和 ReSharper 2016 都没有抱怨这个相当明显的错误:我不得不等到运行时异常才发现代码已损坏。我宁愿早点知道。

我已经探索了 Visual Studio 和 ReSharper 选项,试图找到一种方法让我的工具检测到这些类型的类型不匹配:ReSharper 的“代码模式”是我能得到的最接近的,虽然它可以识别语法错误的模式,它不支持足够深入的类型分析来检测错误。

那么有谁知道让 ReSharper 静态检测 foreach 类型不匹配的方法吗?或者,有没有人知道可以使用的工具?

更新:我最初忽略了从BarFooexplicit 自定义转换运算符——这是explicit,请注意,不是implicit。该演员表操作员的存在似乎严重破坏了工具检测此问题的能力。我已经更新了相关代码以显示行为。

【问题讨论】:

  • 你使用的是什么版本的 R#?
  • ReShaper 2016.1.2,具体来说是 2016 年 5 月发布的。
  • 啊!我没看到更新。我正要告诉你我无法重现这个问题,因为 Resharper 有效地给了我编译时错误,但是如果定义了显式转换,那么我看到的唯一方法是首先使用例如 list.OfType 迭代过滤().
  • Karel,这是关于静态代码分析,而不是关于运行时类型转换:我有一个数百万行的代码库,其中包含未知数量的这些错误,我需要一个工具来帮助查找全部。
  • 你能用显式转换更新你的代码吗?这样我们就不会错过任何东西。

标签: c# visual-studio foreach resharper


【解决方案1】:

嗯,哎呀,所以有一个可靠的答案,由 Eric Lippert 的博客提供。

显然foreach 插入了对explicit 转换运算符的调用(如果有的话)。

ReSharper 允许这样做是正确的,Visual Studio 也是如此。有点。 (就个人而言,我仍然认为 ReSharper 应该警告它,即使它是合法的。)

利珀特先生的几句好话,解释它:

答案是:foreach 循环语义是在泛型添加到语言之前设计的……在泛型世界中,现在枚举的绝大多数序列都是静态类型的,这是一个错误。但是删除它会是一个很大的破坏性更改,所以我们坚持使用它。

...

您可能想知道为什么 C# 编译器不会在使用泛型的现代代码中产生警告。当我在 C# 编译器团队时,我实现了这样的警告,并在 Microsoft 的 C# 代码语料库上进行了尝试。以正确代码产生的警告数量(某人有一个 Animal 序列,但通过其他方式知道它们都是 Giraffe)很大。在正确代码中经常触发的警告是不好的警告,因此我们选择不添加该功能。

(整篇博文都可以在这里找到,虽然令人失望,但也很有启发性。https://ericlippert.com/2013/07/22/why-does-a-foreach-loop-silently-insert-an-explicit-conversion/

【讨论】:

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