如果 C # 不是可选的,为什么还有 break?

当我在 VS2008C # 中创建这样的 switch语句时(人为的) :

switch (state) {
case '1':
state = '2';
case '2':
state = '1';
}

它抱怨说我不能顺道拜访:

控件不能从一个大小写标签(‘ case’1’(0x31) :’)落到另一个大小写标签

如果您不被允许通过,那么 break语句的目的究竟是什么?为什么语言设计者不干脆省略它,自动跳到 switch语句的末尾,而不是强迫我们加入一个不必要的结构呢?

34424 次浏览

If you don't have any code in case 1, you are allowed to fall through, so you can say that "all of these cases share this piece of code"

Basically to make it more familiar to C/C++/Java developers. Personally I think it was a mistake, but that's the reasoning.

I would have preferred a forced block:

case '1':
{
}

Aside from anything else, that would have avoided the weird variable scoping situations for switch/case. You could still have multiple case labels, of course:

case '0':
case '1':
{
}

It might also be nice to be able to list multiple cases more simply:

case '0', '1':
{
}

Oh, and a slight nit-pick about your description of the existing language: you don't have to have a break. It's just that the end of the case has to be unreachable. You can also have throw, goto or return. There may be others that I've missed, too :)

You are allowed to drop through, but you have to do so explicitly with the goto keyword:

switch (state) {
case '1':
state = '2';
goto case '2';
case '2':
state = '1';
break;
}

You can break or gotoin C#, but what you cannot do is not state which you want, because that's a potential source of hard-to-spot bugs.

It's a lot easier to spot that your code says goto when you wanted break (or vice versa) than it is to spot that you forgot to add either.

It might sound stupid, but many a tired two-hour search for the cause of a C++ bug ends in a sudden realisation that you forgot to add a break and your code is falling through all the time. C# avoids that by forcing you to state what you want.

From the horse's mouth (MSDN) Why is the C# switch statement designed to not allow fall-through, but still require a break?.

Quoting the salient bits, this is why they don't allow fall-through:

This implicit fall-through behavior is often used to reduce the amount of code needed and often isn't an issue the first time that code is written. However, as code moves from the initial development phase into a maintenance phase, the code above can lead to subtle errors that are very hard to debug. These errors result from the very common mistake of the developer adding a case, yet forgetting to put a break at the end of the block.

In C#, the switch statement requires that explicit flow control occur at the end of a case, either a break, goto, return, or throw. If the developer desires fall-through semantics, it can be achieved by an explicit goto at the end of a case statement.

And this is why it's not automatic:

As a result of the C# rules requiring explicit flow-control to occur at the end of a case block (most usually a break), many people question why the behavior simply wasn't changed such that fall-through didn't occur. That is, don't make break required, simply change the semantics of switch to not have fall-through for cases. The reason this wasn't done was so that developers who were very used to C++ wouldn't have a hard time understanding what a switch statement was doing.