我在写这段代码:
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.");
}
}
惊讶地发现一个编译错误:
此范围中已经定义了一个名为“ action”的局部变量
这个问题很容易解决。只是摆脱第二个var
就可以了。
显然,在case
块中声明的变量具有parent的作用域switch
,但是我很好奇这是为什么。鉴于C#不允许执行通过其他案件下降(其需要 break
,return
,throw
,或goto case
在每个月底语句case
块),它似乎很奇怪的是,它将使变量声明内一个case
以其它任何使用或冲突与变数case
。换句话说,case
即使执行不能执行,变量似乎也属于语句的一部分。C#通过禁止混淆或容易滥用的其他语言的某些构造,努力提高可读性。但这似乎注定会引起混乱。请考虑以下情形:
如果将其更改为此:
case BindingType.Inherited: var action = (byte)ChangeAction.Inherit; return (x => x.Action == action); case BindingType.ExplicitValue: return (x => x.Action == action);
我得到“ 使用未分配的局部变量'action' ”。这令人困惑,因为在C#中我能想到的所有其他构造中,
var action = ...
都会初始化变量,但是在这里它只是声明了变量。如果我要交换这样的情况:
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);
我得到“ 声明前不能使用局部变量'action' ”。因此,case块的顺序在这里似乎并不十分明显,这很重要-通常我可以按照自己希望的任何顺序编写它们,但是由于
var
必须出现在使用的第一个块中action
,因此我必须调整case
块相应地。如果将其更改为此:
case BindingType.Inherited: var action = (byte)ChangeAction.Inherit; return (x => x.Action == action); case BindingType.ExplicitValue: action = (byte)ChangeAction.SetValue; goto case BindingType.Inherited;
然后我没有收到任何错误,但是从某种意义上说,它看起来像在声明变量之前为变量赋了一个值。
(尽管我想不出您真正想做的任何时间-我什至不知道goto case
今天之前存在)
所以我的问题是,为什么C#的设计师不给case
块自己的局部作用域?是否有任何历史或技术原因?
switch
,我只是对这种设计背后的原因感到好奇。
break
在C#中不会忘记a的常见错误。
action
在switch
语句之前声明变量,或将每种情况放在大括号中,您将获得明智的行为。