我有一个很大的C#代码库,在其中我试图重构和清理其他人的混乱代码。我最近偶然发现了这样的一块:
List<Bar> bars = ... ;
...
foreach (Foo foo in bars) { ... }
...
public class Bar
{
...
public static explicit operator Foo() { ... }
}这种类型不匹配是一个问题。而且,正如您可能预期的那样,代码实际上不起作用:它是一个隐藏在视线中很长时间的bug。
然而,该守则是合法的。Visual 2013和ReSharper 2016都没有抱怨这个相当明显的错误:我不得不等到运行时异常时才发现代码被破坏了。我宁愿早点知道。
我仔细研究了Visual和ReSharper选项,试图找到一种方法让我的工具检测这类类型的不匹配:ReSharper的“代码模式”是我能得到的最接近的,虽然它可以识别出错误的语法模式,但它不支持足够深入的类型分析来检测错误。
那么,有没有人知道一种使ReSharper静态地检测foreach类型不匹配的方法?或者,有人知道有什么工具可以吗?
更新:--我最初省略了一个explicit自定义转换操作符,从Bar到Foo --这是explicit,请注意,不是implicit。这个角色转换操作符的存在似乎对工具检测这一问题的能力造成了极大的破坏。我已经更新了所讨论的代码以显示这种行为。
发布于 2016-10-17 21:11:26
好吧,见鬼,有一个可靠的答案,埃里克·利珀特的博客。
显然,如果有调用,foreach会插入对explicit强制转换操作符的调用。
ReSharper允许这样做是正确的,Visual也是如此。说大也大吧。(就我个人而言,我仍然认为ReSharper应该对此提出警告,即使它是合法的。)
利珀特先生引用了几句很好的话,解释道:
答案是:在将泛型添加到语言中之前,就设计了foreach循环语义。在一个拥有泛型的世界中,绝大多数列举的序列现在都是静态类型的,这是一个错误的特性。但这将是一个巨大的变化,以删除它,所以我们被困在它。 ..。 您可能想知道为什么C#编译器不会在使用泛型的现代代码中产生警告。当我在C#编译器团队工作时,我实现了这样一个警告,并在微软内部的C#代码集上进行了尝试。在正确的代码中产生的警告数量(有人有一系列的动物,但通过其他方式知道它们都是长颈鹿)是很大的。在正确的代码中经常触发的警告是错误的警告,因此我们选择不添加该功能。
(整个博客帖子都可以在这里找到,既令人失望,又具有启发性。)https://ericlippert.com/2013/07/22/why-does-a-foreach-loop-silently-insert-an-explicit-conversion/ )
https://stackoverflow.com/questions/40095271
复制相似问题