在foreach语句中静态检测类型不匹配

Sea*_*ema 1 c# resharper foreach visual-studio

我有一个庞大的C#代码库,我正在尝试重构并清理别人纠结的代码.我最近偶然发现了这样一个块:

List<Bar> bars = ... ;

...

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

...

public class Bar
{
    ...

    public static explicit operator Foo() { ... }
}
Run Code Online (Sandbox Code Playgroud)

这种类型不匹配是一个问题.而且,正如你所期望的,代码实际工作:这是一个的在众目睽睽下掩藏了很久的错误.

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

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

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

更新: 我原来省略,有一个explicit来自自定义转换操作符BarFoo-这是explicit,你要知道,没有implicit.该演员的存在似乎对工具检测此问题的能力造成严重破坏.我已经更新了有问题的代码以显示行为.

Sea*_*ema 6

嗯,哎呀,所以有一个坚实的答案,礼貌Eric Lippert的博客.

如果有的foreach话,显然会向一个explicit演员操作员插入一个调用.

ReSharper和Visual Studio一样允许这样做.有点.(就个人而言,我仍然认为ReSharper应该警告它,即使它是合法的.)

Lippert先生的几句好话,解释说:

答案是:foreach循环语义是在将泛型添加到语言之前设计的......在具有泛型的世界中,枚举的绝大多数序列现在都是静态类型的,这是一种错误.但是删除它会是一个很大的突破性变化,所以我们坚持下去.

...

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

(整个博客文章都可以在这里找到,并且令人失望,因为它很令人失望 .https://ericlippert.com/2013/07/22/why-does-a-foreach-loop-silently-insert-an-explicit - 转换/)