c# - 子范围 & CS0136

标签 c# compiler-construction scope

以下代码无法编译,指出“无法在此范围内声明名为‘st’的局部变量,因为它会给‘st’赋予不同的含义,而‘st’已在‘子’范围内用于表示其他内容“:

        var l = new List<string>();
        l.Find(st => st.EndsWith("12"));
        string st = "why this fails?";

我明白为什么这行不通了:

        string preParent = "";
        {
            string preParent = "Should fail cause we change the meaning";
        }

当我们执行以下操作时,我们得到“CS0103:名称‘postParent’在当前上下文中不存在”:

        {
            string postParent=string.Empty;
        }
        postParent = "Should this work?";

我不明白的是为什么编译器足够聪明,可以看到 postParent 不在范围内,但不允许我定义一个与子范围内使用的变量同名的新变量(这此时显然超出范围)。

编译器是否通过拒绝让我使用变量来简单地强制范围?如果是这样的话,这是有道理的。

===========

编辑:

我想我也觉得有趣的是如何在一个方法中的两个子范围内拥有相同的变量,所以这是有效的:

        {
            string thisWorks= string.Empty;
        }
        {
            string thisWorks= "Should this work?";
        }

我只是有点好奇您可以有两个同名的变量,只要它们处于同一级别(如果您将作用域视为一棵树)。这是有道理的,因为您可以在同一个类的两个方法中使用相同名称的局部变量。

令我感到惊讶的是,编译器能够区分并允许这样做,但不允许使用 postParent 变量。这是技术限制还是设计决定?这就是我真正想要达到的目的;-)

最佳答案

是的,编译器正在强制作用域。请注意,变量的范围是它所属的词法 block - 不仅仅是从声明点开始,而是整个范围。

编译器提示是因为对 postParent 的赋值超出了它的范围(这只是嵌套的大括号)。如果您尝试在当前分配给 postParent 的位置声明一个新变量,问题将出在嵌套 block 上,因为 postParent 的范围将包括嵌套 block ,即使它在声明之前。

范围在 C# 3.0 规范的第 3.7 节中进行了描述。

编辑:回复您的问题编辑。

这只是两个简单的规则:

  • 不能在范围内有另一个同名局部变量时声明局部变量
  • 局部变量的范围是声明发生的 block

我确信语言可以设计成作用域只从声明点开始,但我认为将作用域视为 block 更简单(就语言复杂性而言)——所以所有局部变量都声明在例如,同一 block 具有相同的范围。在考虑捕获变量时,这也让生活变得更加简单 - 因为捕获的内容取决于范围,而嵌套范围使生活变得有趣......

编辑:语言规范对原始的 lambda 表达式示例有这样的说明 - 这是第 7.14.1 节:

The optional anonymous-function-signature of an anonymous function defines the names and optionally the types of the formal parameters for the anonymous function. The scope of the parameters of the anonymous function is the anonymous-function-body. Together with the parameter list (if given), the anonymous-method-body constitutes a declaration space. For this reason, it is a compile-time error for the name of a parameter of the anonymous function to match the name of a local variable, local constant, or parameter whose scope includes the anonymous-method-expression or lambda-expression.

这有帮助吗?

关于c# - 子范围 & CS0136,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/296755/

相关文章:

c - Gcc 中的大数加法结果(阿贝尔群)

c++ - 为什么编译不会为导致未定义行为的代码发出错误

parsing - 在用 Ocaml 编写的编译器中,在哪里/如何声明变量的唯一键?

java - 从 JSF 传递枚举值作为参数(重新访问)

c# - 如何让 StructureMap 返回请求类型的特定实例

c# - XPathSelectElements 总是在带有命名空间的 XML 中返回空?

c# - 我如何要求用户在 C# 中输入

c# - 如何使用 FluentNHibernate 映射具有复杂键类型 (CultureInfo) 的字典

c++ - 由于变量范围导致的段错误

javascript - 自调用函数的括号符号是否在 Javascript 中有用?