为什么在空"while"循环中没有关于可能错误的空语句的警告?



有大量关于编译器警告CS0642的帖子:"可能错误的空语句",我明白它的全部内容。 例如,未使用FileStream实例f,因此这可能是一个错误:

using (var f = File.OpenRead("f.txt")) ; // Possible mistaken empty statement

但是,此while语句不会生成警告,即使x没有机会等于或大于 3 。 为什么?

int x = 1;
while (x < 3) ; // why no warning?

下面是一个示例,其中存在警告,但Timer实例实际上t可以执行某些操作,即触发回调:

using (var t = new Timer((x) => Debug.Print("This"), null, 500, 500)) ; // warning

为什么不一致?

没有不一致。CS0642 不是关于验证您的代码是否有意义或是否执行过,它只是为了捕获一些可能表示错误的语法模式。比较:

int x = 1;
while (x < 3) {}   // no warning
while (x < 3); {}  // CS0642
if (x < 3) ;       // CS0642
using (new object() as IDisposable) ;  // CS0642
using (new object() as IDisposable) {} // no warning
for (; x < 3 ;) ;  // empty statement *and* condition is always true, still no warning

用单个;而不是{ }编写空循环是程序员带来的常见 C 习惯用语(无论好坏(;让这些总是触发 CS0642 可能会产生太多误报。 然而,using从来都不是C成语,因此强制将空块始终写为{ }似乎是合理的。它肯定会捕获一些您可能出错的情况:

TextWriter x = null;
using (x) ;  // CS0642
    x.WriteLine();  // whoops, use of disposed object

诚然,这不是一个可能的模式,甚至将单个语句包装在块中总是很好的做法——即使在 C 中也是如此。

顺便说一句,如果由埃里克·利珀特(Eric Lippert(决定,就不会有;,而且到处都是{ }

空语句功能是多余的,很少需要,并且 容易出错,它为编译器团队创建工作以实现 警告告诉您不要使用它。该功能可能只是 从 C# 1.0 剪切。 (来源(

一个后续的问题是,为什么C#编译器没有明显的努力来警告任何总是truefalse的非平凡条件,这是C编译器的一个相当常见的功能。编译器对始终truefalse的表达式有一些警告(如 CS0464,"与类型'type'的 null 进行比较总是产生'false'"(,但不是一般的警告。这背后可能有一个设计决策,我甚至可能曾经看过Eric Lippert的博客 - 或者我只是想象过那个。无论如何,没有收到任何警告与CS0642无关。

相关内容

  • 没有找到相关文章

最新更新