2009-01-01 38 views
7

question我开始想,为什么下面的例子都属于违法行为在C#中的启发:为什么是的,如果和代表这种方式在C#范围

VoidFunction t = delegate { int i = 0; }; 

int i = 1; 

{ 
    int i = 0; 
} 

int i = 1; 

我只是想知道是否有人知道这种语言是如此设计的确切原因?是否会阻碍糟糕的编程习惯,如果是这样,为什么不发出警告呢?出于性能原因(编译和运行时)或原因是什么?

回答

9

此行为在C#语言规范的第3节中介绍。下面是从规范报价

同样, 发生如在 λ-表达形式的匿名 函数体的任何表达式创建包含匿名的 参数 声明空间功能。 这是一个错误, 局部变量声明空间的两个成员到 具有相同的名称。 块的局部变量声明空间 和嵌套局部变量 声明空间包含具有相同名称的元素 的错误。因此,在 嵌套声明空间内,不是 可能声明局部变量 或常量,其名称与 局部变量或常量声明空间中的 相同。

我认为更容易阅读的方法是,为了变量声明(和许多其他块相关函数)的目的,lambda /匿名委托块被视为与正常块没有区别。至于为什么这种语言是这样设计的,规范没有明确规定。我的意见虽然简单。如果代码被视为另一个块,那么它使代码分析例程变得更容易。您可以保留现有的所有例程,以分析块的语义错误和名称解析。当您考虑可变提升时,这一点尤为重要。 Lambdas最终将会是一个不同的功能,但他们仍然可以在声明点访问所有范围变量。

+0

看来,问题在于他们没有区分删除前后的范围。这可能会使编译器供应商的代码变得相当简单,但是会增加程序员的负担。 – 2009-01-01 17:53:09

+0

@安德斯,是的,但在这种情况下,有一个工作。运输是一个持续不断的压力,当面临在大型工作项目之间进行选择以获得一小部分功能或小项目(这使得功能缺乏明确并且可以稍后逆转)时,小型工作项目通常会获胜。 – JaredPar 2009-01-01 18:04:48

+1

我不明白这可能会如何很难实现,至少不是如果情况。只需使用一个堆栈并完成它。它闻到了很多臭虫或测量的痕迹,以防止人们在脚上拍摄自己的脚,这些脚采用了一些不错的功能。 – 2009-01-01 19:16:24

2

我认为这样做是为了让内部作用域可以访问在外部作用域中声明的变量。如果允许您重写外部范围中存在的变量,则可能会出现混淆意图的行为。所以他们可能决定通过阻止问题的发生来解决问题。

0

我认为这样可以防止开发者在脚下自己拍摄。