last day (17 days later) » 

13:46
86
A: In C#, why are variables declared inside a try block limited in scope?

Ben AaronsonWhat if your code was: try { MethodThatMightThrow(); var firstVariable = 1; } catch {} try { var secondVariable = firstVariable; } catch {} Now you'd be trying to use an undeclared variable (firstVariable) if your method call throws. Note: The above example specifically answers the ...

@SebastianRedl I think Peter's reason is just as important as this one, if not more. But the OP explicitly said "Consistency-sake aside", so I was demonstrating that even if you wanted to make a special case for try/catch blocks (for some reason), you'd run into problems making it work
@jpmc26 Good point, I've updated the answer
@svick Yes, that's true. In fact if you declare a variable outside a try...catch, then make sure to initialize it in both the try and the catch, the compiler does allow using that variable after the try...catch. The difference between that and what you're describing is just where the variable is declared. So perhaps I should undo my last edit.
"Now you'd be trying to use an undeclared variable (firstVariable) if your method call throws." why is the error "the name 'firstVariable' does not exist in the current context" better than "use of unassigned local variable 'firstVariable'", which is what would happen if it is declared at the outer scope and not set to a value in the catch?
@PeteKirkham I'm not sure what you mean by "better than"? The compiler disallows both of these
If you agree that you'd get a more or less equivalent error whether or not the block created scope, your argument as to why the block creates scope is invalid.
@PeteKirkham The advantage the OP suggested to not creating scope is so that you could declare a variable in a try, then use it outside. As I showed, this can lead to a situation where the compiler doesn't know whether or not what you're written is valid- you may or may not have declared the variable by the time you use it. So instead, the compiler says this is always invalid, so you're safe at compile time. In the situation you're talking about (initialise in try, but not in catch), the compiler also says this is always invalid.
@PeteKirkham So it takes a consistent approach to both: disallow at compile-time if it can't verify for sure at compile time that it is valid (i.e. that it has been declared and initialised). Allowing the OP's suggestion would prevent it from doing that, and so make it inconsistent. Does that answer your point? I may still be misunderstanding what you're saying, in which case could you expand on what you mean?
13:46
The compiler already tracks whether or not it is assigned to. You haven't presented a case where the OP's suggestion creates an ambiguity which is not already dealt with by the existing definite assignment mechanism, so I don't see any advantage.
Well, if the OP's suggestion was allowed, what code could be written that the definite assignment mechanism would verify WAS definitely assigned, where the variable was declared inside the try block? If there isn't any, then the kind of thing the OP wants to do would be impossible anyway, so there'd be no reason to make an exception to the scoping rules
Also the difference between assignment and declaration is significant. int a; try { a = 1; } catch { a = 2; } is legal. But try { int a = 1; } catch { int a = 2; } and try { int a = 1; } catch { a = 2; } can't be because you might end up declaring something twice (first example) or assigning to it before declaring (second example)
Declaring something twice in the same scope is already illegal.
It would be just as {int a; try { a=7;} catch { int a;}
If we can agree that declaring and initialising a variable is equivalent to doing these as separate statements, and that declaring a variable cannot throw. It is also always safe to move a declaration upwards in a block. We then can simulate the OP's scheme by moving all declarations outside the try block. The compiler's definite assignment check knows about try/catch, so there is no additional source of error.
So the question is - what additional error is being found that would not be reported if the OP's scheme was in place?
(I'm off to get my lunch now)

  last day (17 days later) »