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