2013-07-10 125 views
0

我有一个简单的问题,我似乎无法理解。C#有效语法(IF语句中没有括号的变量声明)

为什么这个有效的C#:

if (node != null) 
{ 
    string fullAddress = node.InnerText; 
} 

这是不是?

if (node != null) 
    string fullAddress = node.InnerText; 

这是编译器中的错误还是这是打算?

+0

你期望第二个版本要做什么?如果允许,'fullAddress'在单行之外是不可见的...(检查C#规范 - 最可能的声明不是语句) –

+0

@Alexei Levenkov我期望它没有语法错误! – clamchoda

+0

我的意思是你建议这个代码产生什么结果(忽略它是无效的C#语法) - 即在错误条件下if'语句之后'fullAddress'变量是如何可见的。 –

回答

2

这是正常现象,如果你还记得if需要一个说法是有道理的 - 所以,如果这样的语法允许它被宣布后声明变量的范围将立即结束。

详细覆盖在C#5.0规范部分8.5(感谢罗布哈维用于链路)和语法部分B.2.5:

8.5节:

的声明陈述声明一个局部变量或常数。声明语句在块中是允许的,但不允许作为嵌入语句。

语法从部分B.2.5:

statement: 
    labeled-statement 
    declaration-statement 
    embedded-statement 

embedded-statement: 
    block 
    ... 

if-statement: 
    if ( boolean-expression ) embedded-statement 

正如你可以看到变量声明(declaration-statement)不是embedded-statement,因此不能在if-statement使用。 C#规格位置

注:

  • 旧版本可以在MSDN网上找到(即上面提到的来自Anirudh的Section 8.5答案)
  • 最新自带VS安装,通常位于“Program Files(x86)\ Microsoft Visual Studio 11.0 \ VC#\ Specifications \ 1033 \ CSharp Language Specification.docx”文件夹中。另请参见Where can I find the C# 5 language specification?
7

因为您正在定义一个没有封闭范围的本地变量。

+0

+1这比我将要解释的要简单得多。 –

+0

谢谢。希望我对C#规范有足够的了解,以引用说明规则的那部分内容,但我怀疑它是暗指的,而不是陈述的。 –

+0

@RobertHarvey它在说明中或多或少是明确的 - 我在我的答案中添加了摘录。 –

3

当你写没有括号的if,编译器将单个语句好像有牙套,所以:

if (node != null) 
    string fullAddress = node.InnerText; 

基本上被变成了:

if (node != null) 
{ 
    string fullAddress = node.InnerText; 
} 

但是,请注意fullAddress的范围只在大括号内,所以变量永远不能使用。编译器足够聪明,可以知道这一点,因此它将其标记为错误,因为它知道没有一个理智的程序员会这样做。 :)

我认为这实际上是.NET编译器中的一个常见主题 - 它们有很多理智检查,以确保您不会做任何没有意义的事情,并且通常会优化基于输出的在各种代码模式。

+0

谢谢迈克尔。我总是抛出它为什么会产生语法错误,但“没有理智的程序员会这样做”,编译器知道它实际上是正确的答案。我从来没有想过如何无用的“无效”的语法。我赞同你的回答,因为它帮助我理解,但是阿列克谢从B.2.5节获得了语法奖励积分! – clamchoda

5

msdn说这

声明语句可以在块,但不允许 作为嵌入语句。

+0

啊,你去了。 –

0
if (node != null) 
    string fullAddress = node.InnerText; 

这是写代码,你不必使用括号的视觉基本风格。而且,在C#中,如果我们不给出括号,则只执行一行语句。但是,如果我们需要执行多行代码,那么我们将不得不使用括号。