我刚刚碰到了一个非常奇怪的C#行为,如果有人能向我解释,我会很高兴。
说,我有以下课程:
class Program
{
static int len = 1;
static void Main(string[] args)
{
Func<double, double> call = len => 1;
len = 1; // error: 'len' conflicts with the declaration 'csutils.Program.len'
Program.len = 1; // ok
}
}
正如我所知,在评论中,我在我的视野中有以下对象:len
变量和call
。
在lambda内部,我有本地参数len
和Program.len
变量。
但是,在声明了这样的lambda之后,我再也不能在len
方法的范围内使用Main
变量了。我必须要求Program.len
将其重写为anyOtherNameBesidesLen => 1
。
为什么会这样?这是语言的正确行为,还是我遇到了语言中的错误?如果这是正确的行为,语言架构如何证明它是正确的?为什么lambda捕获变量可以搞乱lambda之外的代码?
编辑: Alessandro D&#39; Andria有很好的例子(评论中的第1和第2)。
EDIT2: 这段代码(相当于我在开头写的那段)是非法的:
class Program
{
static int len = 0;
static void Main(string[] args)
{
{
int len = 1;
}
int x = len;
}
}
然而,尽管具有完全相同的范围结构,但此代码完全合法:
class Other
{
static int len = 0;
class Nested
{
static void foo()
{
int len = 1;
}
static int x = len;
}
}
答案 0 :(得分:4)
据我所知,在这种情况下发出编译时错误是正确的,因为在子作用域中不允许使用len
(即匿名函数的参数(lambda)) )当在同一方法中的包含范围内使用不具有限定条件的相同符号len
时(或其他内容)。
但是,错误文本令人困惑。
如果您更改为:
static int len = 1;
static void Main(string[] args)
{
len = 1;
Func<double, double> call = len => 1; // error CS0136: A local variable named 'len' cannot be declared in this scope because it would give a different meaning to 'len', which is already used in a 'parent or current' scope to denote something else
}
错误文字更好。
其他一些例子:
static int len = 1;
static void Main()
{
var len = 3.14; // OK, can hide field
Console.WriteLine(len); // OK, 'len' refers to local variable
Console.WriteLine(Program.len); // OK, hidden field can still be accessed, with proper qualification
}
上面的示例显示,只要始终使用限定条件访问该字段(在.
成员访问运算符之后),就可以隐藏具有相同名称的本地变量(或方法参数)的字段。< / p>
static int len = 1;
static void Main()
{
if (DateTime.Today.DayOfWeek == DayOfWeek.Saturday)
{
var len = 3.14;
Console.WriteLine(len);
}
Console.WriteLine(len); // error CS0135: 'len' conflicts with the declaration 'csutils.Program.len'
}
这表示当您尝试在父作用域中使用字段 len
时,无法在子作用域中隐藏len
。错误文本再次受到批评。
static int len = 1;
static void Main()
{
Console.WriteLine(len);
if (DateTime.Today.DayOfWeek == DayOfWeek.Saturday)
{
var len = 3.14; // error CS0136: A local variable named 'len' cannot be declared in this scope because it would give a different meaning to 'len', which is already used in a 'parent or current' scope to denote something else
Console.WriteLine(len);
}
}
你看到了类比。
当然,在此之前已经多次提到过这些问题,例如Why can't a duplicate variable name be declared in a nested local scope?
答案 1 :(得分:0)
错误消息是错误的,它应该指向包含lambda的行。
正如你所说&#34;在lambda内部,我有本地参数len
和Program.len
变量&#34; ,问题是lambda的名称参数与变量len
冲突。所以问题只在于lambda表达式。
问题不在于您&#34;不能再使用len
方法Main
方法&#34; 。这是两者之间的冲突,根本不会编译任何代码。