Switch statement fallthrough in C#?

Switch statement fallthrough is one of my personal major reasons for loving switch vs. if/else if constructs. An example is in order here:

static string NumberToWords(int number)
{
    string[] numbers = new string[] 
        { "", "one", "two", "three", "four", "five", 
          "six", "seven", "eight", "nine" };
    string[] tens = new string[] 
        { "", "", "twenty", "thirty", "forty", "fifty", 
          "sixty", "seventy", "eighty", "ninety" };
    string[] teens = new string[]
        { "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen",
          "sixteen", "seventeen", "eighteen", "nineteen" };

    string ans = "";
    switch (number.ToString().Length)
    {
        case 3:
            ans += string.Format("{0} hundred and ", numbers[number / 100]);
        case 2:
            int t = (number / 10) % 10;
            if (t == 1)
            {
                ans += teens[number % 10];
                break;
            }
            else if (t > 1)
                ans += string.Format("{0}-", tens[t]);
        case 1:
            int o = number % 10;
            ans += numbers[o];

            break;
        default:
            throw new ArgumentException("number");
    }
    return ans;
}

The smart people are cringing because the string[] s should be declared outside the function: well, they are, this is just an example.

The compiler fails with the following error:

Control cannot fall through from one case label ('case 3:') to another
Control cannot fall through from one case label ('case 2:') to another

Why? And is there any way to get this sort of behaviour without having three if s?


(Copy/paste of an answer I provided elsewhere)

Falling through switch - case s can be achieved by having no code in a case (see case 0 ), or using the special goto case (see case 1 ) or goto default (see case 2 ) forms:

switch (/*...*/) {
    case 0: // shares the exact same code as case 1
    case 1:
        // do something
        goto case 2;
    case 2:
        // do something else
        goto default;
    default:
        // do something entirely different
        break;
}

The "why" is to avoid accidental fall-through, for which I'm grateful. This is a not uncommon source of bugs in C and Java.

The workaround is to use goto, eg

switch (number.ToString().Length)
{
    case 3:
        ans += string.Format("{0} hundred and ", numbers[number / 100]);
        goto case 2;
    case 2:
    // Etc
}

The general design of switch/case is a little bit unfortunate in my view. It stuck too close to C - there are some useful changes which could be made in terms of scoping etc. Arguably a smarter switch which could do pattern matching etc would be helpful, but that's really changing from switch to "check a sequence of conditions" - at which point a different name would perhaps be called for.


Switch fallthrough is historically one of the major source of bugs in modern softwares. The language designer decided to make it mandatory to jump at the end of the case, unless you are defaulting to the next case directly without processing.

switch(value)
{
    case 1:// this is still legal
    case 2:
}
链接地址: http://www.djcxy.com/p/2424.html

上一篇: C#switch语句中的变量声明

下一篇: 在C#中切换语句贯穿始终?