我有一个庞大的C#代码库,我正在尝试重构并清理别人纠结的代码。我最近偶然发现了这样一个块:
PATH
这种类型不匹配是一个问题。并且,正如您所料,代码实际上不会正常工作:这是一个长期以来一直隐藏的错误。
但是,代码是 legal 。 Visual Studio 2013和ReSharper 2016都没有抱怨这个相当明显的错误:我不得不等到运行时异常才发现代码被破坏了。我宁愿早点发现。
我在Visual Studio和ReSharper选项中试图找到一种方法让我的工具检测到这些类型的不匹配:ReSharper的“代码模式”是我能得到的最接近的,虽然它可以识别语法故障模式,它不支持足够深入的类型分析来检测错误。
那么有没有人知道让ReSharper静态检测bin
类型不匹配的方法?或者,有没有人知道可以使用的工具?
更新:我最初遗漏了从List<Bar> bars = ... ;
...
foreach (Foo foo in bars) { ... }
...
public class Bar
{
...
public static explicit operator Foo() { ... }
}
到foreach
的{{1}}自定义投放操作符 - 那是explicit
,请注意,不是Bar
。该演员的存在似乎对工具检测此问题的能力造成严重破坏。我已经更新了有问题的代码以显示行为。
答案 0 :(得分: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-conversion/)