关于compiler warning CS0642: "Possible mistaken empty statement"的帖子有吨,我了解其中的全部内容。例如,没有使用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
为什么不一致?
答案 0 :(得分:3)
没有不一致。 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中删除。 (Source.)
一个后续问题是,为什么C#编译器没有做出明显的努力来警告总是true
或false
的任何非平凡条件,这是C编译器的一个相当普遍的功能。编译器对于始终为true
或false
的表达式具有 some 警告(例如CS0464,“与类型为'type'的null进行比较始终会生成'false'”),但不是一般的。这背后可能有一个设计决定,我什至可能曾经见过Eric Lippert博客有关它的报道,或者也许我只是想象中的那样。无论如何,没有任何警告与CS0642无关。