为什么这个编译错误

编程入门 行业动态 更新时间:2024-10-19 06:24:20
本文介绍了为什么这个编译错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

为什么如果我写

void Main(){字符串值 = @"C:";if (!string.IsNullOrEmpty(value)) {字符串 sDirectory = Path.GetDirectoryName(value);}}

它编译.

如果我写了

void Main(){字符串值 = @"C:";if (!string.IsNullOrEmpty(value))字符串 sDirectory = Path.GetDirectoryName(value);}

不是吗?

很明显,从纯函数的角度来看,第二个示例中的变量声明是无用的,但是为什么它神奇地在第一 示例,所以?

两个示例生成的 IL 代码完全相同.

IL_0000: ldstr "C:"IL_0005:stloc.0IL_0006: ldloc.0IL_0007:调用 System.String.IsNullOrEmptyIL_000C:brtrue.s IL_0015IL_000E: ldloc.0IL_000F:调用 System.IO.Path.GetDirectoryName

忘记说明为第二种情况生成 IL 代码(因此不可编译的情况),在没有 string sDirectory 的情况下编译就足够了=

解决方案

if 语句的产生式在 C# 规范的第 8.7.1 节中,它是这样的:

if 语句:if ( boolean-expression ) 嵌入语句if ( boolean-expression ) 嵌入语句 else 嵌入语句

C# 规范第 8 节的开头明确谈到了embedded-statement 产生式,然后给出了它的规范:

嵌入语句:堵塞空语句表达式语句选择声明迭代语句跳转语句尝试语句检查语句未经检查的语句锁定语句使用语句产量声明

嵌入式语句非终结符用于出现在其他语句中的语句.使用嵌入语句而不是语句排除了在这些上下文中使用声明语句和标记语句.例子

void F(bool b) {如果 (b)国际我= 44;}

导致编译时错误,因为 if 语句需要嵌入语句而不是 if 分支的语句.如果允许使用此代码,则将声明变量 i,但永远无法使用它.但是请注意,通过将 i 的声明放在块中,该示例是有效的.

请注意,赋值算作表达式语句 - 但局部变量声明不算.(这是一个声明语句,如第 8.5 节所述.)

就设计决策而言,声明一个您随后无法使用的变量是没有意义的 - 所以编译器阻止您这样做是好的.

Why if I write

void Main() { string value = @"C:"; if (!string.IsNullOrEmpty(value)) { string sDirectory = Path.GetDirectoryName(value); } }

it compiles.

And in case if I write

void Main() { string value = @"C:"; if (!string.IsNullOrEmpty(value)) string sDirectory = Path.GetDirectoryName(value); }

It doesn't ?

It's clear that from pure functional point of view the declaration of the variable in the second example is useless, but why it magically becomes usefull in first example, so ?

The IL code produced by both examples is exactly the same.

IL_0000: ldstr "C:" IL_0005: stloc.0 IL_0006: ldloc.0 IL_0007: call System.String.IsNullOrEmpty IL_000C: brtrue.s IL_0015 IL_000E: ldloc.0 IL_000F: call System.IO.Path.GetDirectoryName

EDIT:

Forgot to mantion that to produce the IL code for the second case (so the case which is not compilable), it's enough to compile without string sDirectory =

解决方案

The production for an if statement is in section 8.7.1 of the C# spec, and it goes like this:

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

The start of section 8 of the C# spec explicitly talks about the embedded-statement production after giving the specification for it:

embedded-statement: block empty-statement expression-statement selection-statement iteration-statement jump-statement try-statement checked-statement unchecked-statement lock-statement using-statement yield-statement

The embedded-statement nonterminal is used for statements that appear within other statements. The use of embedded-statement rather than statement excludes the use of declaration statements and labeled statements in these contexts. The example

void F(bool b) { if (b) int i = 44; }

results in a compile-time error because an if statement requires an embedded-statement rather than a statement for its if branch. If this code were permitted, then the variable i would be declared, but it could never be used. Note, however, that by placing i’s declaration in a block, the example is valid.

Note that an assignment counts as an expression-statement - but a local variable declaration doesn't. (That's a declaration-statement, as in section 8.5.)

In terms of a design decision, it makes no sense to declare a variable that you can't then use - so it's good that the compiler stops you from doing it.

更多推荐

为什么这个编译错误

本文发布于:2023-11-09 20:59:27,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1573417.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:错误

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!