mat*_*thk 1 c# lambda programming-languages lexical-scope
为什么C#不支持alpha转换?
int n = 3;
int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
int oddNumbers = numbers.Count(n => n % 2 == 1);
Console.Out.WriteLine("N value = " + n);
Run Code Online (Sandbox Code Playgroud)
产量:
名为'n'的局部变量不能在此范围内声明,因为它会给'n'赋予不同的含义,'n'已在'父或当前'范围内用于表示其他内容
有没有我不知道的颗粒原因,因为它听起来很傻?
Eri*_*ert 11
首先,你对奇怪的测试是错误的.
你的问题的答案是否定你的问题的前提.这与alpha转换没有任何关系.
它也与"词汇范围"没有任何关系,其中leppie似乎意味着与我对词汇范围的理解不同的东西.C#是一种词法范围的语言.
现在,我想强调,在C#中声明两个本地人是非法的,其中一个隐藏另一个.隐藏在其他范围内是完全合法的; 类型参数可以隐藏外部类型参数(虽然这样做真的非常愚蠢;不要这样做.)字段可能隐藏基类字段(尽管你应该将隐藏字段标记为'新',以强调这一事实.)本地人可能隐藏一种方法.等等.
但是本地人可能不会隐藏另一个本地,因为(1)这样做会导致bug场,并且(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
}
}
Run Code Online (Sandbox Code Playgroud)
您得到的错误是因为您违反了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
}
}
Run Code Online (Sandbox Code Playgroud)
这是合法的,因为现在n的两个用法是在非重叠的范围内.
这个问题与alpha转换没有任何关系.C#在需要时进行alpha转换就好了.
这是因为 C#具有词法范围,编译器可以确定您违反了此规则.这并不是C#缺乏词汇范围的证据; 它证明它具有词汇范围.
有关此规则的更多信息,请参阅我关于此主题的文章:
http://blogs.msdn.com/b/ericlippert/archive/2009/11/02/simple-names-are-not-so-simple.aspx
归档时间: |
|
查看次数: |
477 次 |
最近记录: |