Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

I was writing this code: private static Expression<Func<Binding, bool>> ToExpres

ID: 643883 • Letter: I

Question

I was writing this code:

private static Expression<Func<Binding, bool>> ToExpression(BindingCriterion criterion)
{
    switch (criterion.ChangeAction)
    {
        case BindingType.Inherited:
            var action = (byte)ChangeAction.Inherit;
            return (x => x.Action == action);
        case BindingType.ExplicitValue:
            var action = (byte)ChangeAction.SetValue;
            return (x => x.Action == action);
        default:
            // TODO: Localize errors
            throw new InvalidOperationException("Invalid criterion.");
    }
}
And was surprised to find a compile error:

A local variable named 'action' is already defined in this scope

It was a pretty easy issue to resolve; just getting rid of the second var did the trick.

Evidently variables declared in case blocks have the scope of the parent switch, but I'm curious as to why this is. Given that C# does not allow execution to fall through other cases (it requires break, return, throw, or goto case statements at the end of every case block), it seems quite odd that it would allow variable declarations inside one case to be used or conflict with variables in any other case. In other words variables appear to fall through case statements even though execution cannot. C# takes great pains to promote readability by prohibiting some constructs of other languages that are confusing or or easily abused. But this seems like it's just bound to cause confusion. Consider the following scenarios:

If were to change it to this:

case BindingType.Inherited:
    var action = (byte)ChangeAction.Inherit;
    return (x => x.Action == action);
case BindingType.ExplicitValue:
    return (x => x.Action == action);
I get "Use of unassigned local variable 'action'". This is confusing because in every other construct in C# that I can think of var action = ... would initialize the variable, but here it simply declares it.

If I were to swap the cases like this:

case BindingType.ExplicitValue:
    action = (byte)ChangeAction.SetValue;
    return (x => x.Action == action);
case BindingType.Inherited:
    var action = (byte)ChangeAction.Inherit;
    return (x => x.Action == action);
I get "Cannot use local variable 'action' before it is declared". So the order of the case blocks appears to be important here in a way that's not entirely obvious -- Normally I could write these in any order I wish, but because the var must appear in the first block where action is used, I have to tweak case blocks accordingly.

If were to change it to this:

case BindingType.Inherited:
    var action = (byte)ChangeAction.Inherit;
    return (x => x.Action == action);
case BindingType.ExplicitValue:
    action = (byte)ChangeAction.SetValue;
    goto case BindingType.Inherited;
Then I get no error, but in a sense, it looks like the variable is being assigned a value before it's declared.
(Although I can't think of any time you'd actually want to do this -- I didn't even know goto case existed before today)

So my question is, why didn't the designers of C# give case blocks their own local scope? Are there any historical or technical reasons for this?

Explanation / Answer

I think a good reason is that in every other case, the scope of a

Hire Me For All Your Tutoring Needs
Integrity-first tutoring: clear explanations, guidance, and feedback.
Drop an Email at
drjack9650@gmail.com
Chat Now And Get Quote