我只是碰到了一个非常奇怪的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
}
}
Run Code Online (Sandbox Code Playgroud)
当我得到它时,在评论的路线中,我在我的视野中有以下物体:len变量和call.在lambda里面,我有本地参数len和Program.len变量.
然而,在声明这样的lambda之后,我不能再len在Main方法范围内使用变量了.我必须要么将它Program.len重写为lambda anyOtherNameBesidesLen => 1.
为什么会这样?这是语言的正确行为,还是我遇到了语言中的错误?如果这是正确的行为,语言架构如何证明它是正确的?为什么lambda捕获变量可以搞乱lambda之外的代码?
编辑:亚历山德罗·德安德里亚有很好的例子(他的评论中的第1和第2).
edit2:这段代码(等于我在开头写的那段)是非法的:
class Program
{
static int len = 0;
static void Main(string[] args)
{
{
int len = 1;
}
int x = len;
}
}
Run Code Online (Sandbox Code Playgroud)
但是,尽管具有完全相同的范围结构,但此代码完全合法:
class Other
{
static int len = 0;
class Nested
{
static void foo()
{
int len = 1;
}
static int x = len;
}
}
Run Code Online (Sandbox Code Playgroud)
据我所知,在这种情况下发出编译时错误是正确的,因为当没有限定的相同符号是时,不允许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
}
Run Code Online (Sandbox Code Playgroud)
错误文本更好。
其他一些例子:
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
}
Run Code Online (Sandbox Code Playgroud)
上面的示例表明,隐藏具有相同名称的局部变量(或方法参数)的字段是可以的,只要该字段始终按限定条件进行访问(在.成员访问运算符之后)。
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'
}
Run Code Online (Sandbox Code Playgroud)
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);
}
}
Run Code Online (Sandbox Code Playgroud)
你看到这个类比了。
当然,这些问题之前已经多次提到过,例如为什么不能在嵌套局部作用域中声明重复的变量名?
| 归档时间: |
|
| 查看次数: |
181 次 |
| 最近记录: |