com*_*cme 47 c# scope language-design
也许这个问题之前已经得到了回答,但是这个词if经常出现,很难找到它.
这个例子没有意义(表达式总是正确的),但它说明了我的问题.
为什么此代码有效:
StringBuilder sb;
if ((sb = new StringBuilder("test")) != null) {
Console.WriteLine(sb);
}
Run Code Online (Sandbox Code Playgroud)
但是这段代码不是:
if ((StringBuilder sb = new StringBuilder("test")) != null) {
Console.WriteLine(sb);
}
Run Code Online (Sandbox Code Playgroud)
我发现了一个关于while声明的类似问题.那里接受的答案说,在一个while声明中,它意味着变量将在每个循环中定义.但是对于我的if陈述例子,情况并非如此.
那么我们不允许这样做的原因是什么?
Ree*_*sey 38
这是因为C#语言规范的第8.5.1节.状态:
此外,局部变量声明中的变量初始值设定项与声明后立即插入的赋值语句完全对应.
这基本上意味着,当你这样做时:
StringBuilder sb = new StringBuilder("test")
Run Code Online (Sandbox Code Playgroud)
实际上,你做的完全相同:
StringBuilder sb; sb = new StringBuilder("test")
Run Code Online (Sandbox Code Playgroud)
因此,对于您的检查不再有返回值!= null,因为赋值不是单个表达式,而是一个语句,它是一个由标识符后跟表达式组成的局部变量声明符.
语言规范给出了这个例子,说明了这个:
void F() {
int x = 1, y, z = x * 2;
}
Run Code Online (Sandbox Code Playgroud)
完全等同于:
void F() {
int x; x = 1;
int y;
int z; z = x * 2;
}
Run Code Online (Sandbox Code Playgroud)
Jec*_*oms 24
尝试C#7的模式匹配.
使用你的例子:
if (new StringBuilder("test") is var sb && sb != null) {
Console.WriteLine(sb);
}
Run Code Online (Sandbox Code Playgroud)
这与语句和表达式之间的区别有关.表达式具有值,而语句不具有值.
使用您的示例,请注意以下分类:
StringBuilder sb; // statement
sb = new StringBuilder("test") // expression
StringBuilder sb = new StringBuilder("test"); // statement
Run Code Online (Sandbox Code Playgroud)
请注意,只有中间部分是表达式.
现在我们转到你的条件语句.使用not-equals运算符的语法是
expression != expression
Run Code Online (Sandbox Code Playgroud)
因此,在!=你需要的东西实际上有一些价值(这才有意义).因此,您不能在运营商的任何一方发表声明.这就是为什么你的代码的一个版本工作,而另一个版本没有.
代替:
if ((StringBuilder sb = new StringBuilder("test")) != null) {
Console.WriteLine(sb);
}
Run Code Online (Sandbox Code Playgroud)
还可以这样写:
for (StringBuilder sb = new StringBuilder("test"); sb != null; sb = null) {
Console.WriteLine(sb);
}
Run Code Online (Sandbox Code Playgroud)
如果您的变量不为空,则此 for 循环将执行一次。在循环结束时,您的临时变量设置为 null。然后循环条件评估为假,并且在执行右大括号后继续下一条语句。完全按照您的 if 语句最初的意图。