首先,您对奇数的测试是错误的。
你的问题的答案是否认你的问题的前提。这与 alpha 转换无关。
它也与“词法作用域”无关,leppie 似乎意味着与我对词法作用域的理解不同的东西。C# 是一种词法范围的语言。
现在,我想强调的是,在 C# 中声明两个局部变量,一个隐藏另一个局部变量是非法的。隐藏在其他范围内是完全合法的;类型参数可能会隐藏外部类型参数(尽管这样做真的很愚蠢;不要那样做。)字段可能会隐藏基类字段(尽管您应该将隐藏字段标记为“新”,以强调这一事实.) 本地人可能会隐藏一个方法。等等。
但是一个本地人可能不会隐藏另一个本地人,因为(1)这样做会产生错误农场,并且(2)它违反了关于使用简单名称的更一般的规则。
关于名称的规则是这里有趣的规则。如果你这样做,你会得到一个类似的错误:
class C
{
int n;
void M()
{
Console.WriteLine(n); // n means this.n
Func<double, double> f = n=>n; // n means the formal parameter
}
}
您遇到的错误是因为您违反了 C# 规则,即简单名称必须在首次使用的本地范围内具有一致的含义。
'n' 在一行表示一件事而在下一行表示完全不同的程序是令人困惑和容易出错的,因此是非法的。
如果你想这样做,那么“n”的两个含义必须在不重叠的范围内:
class C
{
int n;
void M()
{
{
Console.WriteLine(n); // n means this.n
}
Func<double, double> f = n=>n; // n means the formal parameter
}
}
这将是合法的,因为现在 n 的两种用法都在不重叠的范围内。
该问题与 alpha 转换无关。C# 在需要时可以很好地进行 alpha 转换。
正是因为C# 是词法范围的,所以编译器可以确定您违反了此规则。这并不是 C# 缺乏词法作用域的证据;这是它具有词法作用域的证据。
有关此规则的更多想法,请参阅我关于该主题的文章:
http://blogs.msdn.com/b/ericlippert/archive/2009/11/02/simple-names-are-not-so-simple.aspx