Why is the scope of if and delegates this way in c

2020-07-09 08:44发布

问题:

Inspired by this question I began wondering why the following examples are all illegal in c#:

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

int i = 1;

and

{
   int i = 0;
}

int i = 1;

I'm just wondering if anyone knew the exact reason why the language was designed this way? Is it to discourage bad programming practice, and if so why not just issue a warning?, for performance reasons (compiling and when running) or what is the reason?

回答1:

This behavior is covered in section 3 of the C# language specification. Here is the quote from the spec

Similarly, any expression that occurs as the body of an anonymous function in the form of a lambda-expression creates a declaration space which contains the parameters of the anonymous function. It is an error for two members of a local variable declaration space to have the same name. It is an error for the local variable declaration space of a block and a nested local variable declaration space to contain elements with the same name. Thus, within a nested declaration space it is not possible to declare a local variable or constant with the same name as a local variable or constant in an enclosing declaration space.

I think the easier way to read this is that for the purpose of variable declaration (and many other block related functions) a lambda/anonymous delegate block are treated no different than a normal block.

As to why the the language was designed this way the spec does not explicitly state. My opinion though is simplicity. If the code is treated as just another block then it makes code analysis routines easier. You can preserve all of your existing routines to analyze the block for semantical errors and name resolution. This is particularly important when you consider variable lifting. Lambdas will eventually be a different function but they still have access to all in scope variables at the declaration point.



回答2:

I think it is done this way so that the inner scope can access variables declared in the outer scope. If you were allowed to over-write variables existing in the outer scope, there may be confusion about what behavior was intended. So they may have decided to resolve the issue by preventing it from happening.



回答3:

I think it's this way to prevent devs from shooting themselves in the foot.