Switch语句贯穿是我个人喜欢Switch vs. if/else if结构的主要原因之一。下面是一个例子:

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;
}

聪明的人畏缩不前,因为字符串[]应该在函数之外声明:好吧,它们是,这只是一个例子。

编译器失败,出现以下错误:

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

为什么?有没有什么方法能让这种行为不需要三个如果呢?


当前回答

“为什么”是为了避免意外摔倒,对此我很感激。这是C和Java中常见的错误来源。

解决办法是使用goto,例如。

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

在我看来,开关/机箱的总体设计有点不太理想。它太接近C语言了——在范围等方面可以做一些有用的改变。可以说,一个更聪明的开关,可以进行模式匹配等将是有帮助的,但这实际上是从开关到“检查条件序列”的变化-在这一点上,可能需要一个不同的名称。

其他回答

您忘记在情形3中添加“break;”语句。在情形2中,你把它写到if块中。 因此,试试这个吧:

case 3:            
{
    ans += string.Format("{0} hundred and ", numbers[number / 100]);
    break;
}


case 2:            
{
    int t = (number / 10) % 10;            
    if (t == 1)            
    {                
        ans += teens[number % 10];                
    }            
    else if (t > 1)                
    {
        ans += string.Format("{0}-", tens[t]);        
    }
    break;
}

case 1:            
{
    int o = number % 10;            
    ans += numbers[o];            
    break;        
}

default:            
{
    throw new ArgumentException("number");
}

“为什么”是为了避免意外摔倒,对此我很感激。这是C和Java中常见的错误来源。

解决办法是使用goto,例如。

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

在我看来,开关/机箱的总体设计有点不太理想。它太接近C语言了——在范围等方面可以做一些有用的改变。可以说,一个更聪明的开关,可以进行模式匹配等将是有帮助的,但这实际上是从开关到“检查条件序列”的变化-在这一点上,可能需要一个不同的名称。

他们故意省略了这种行为,以避免这种行为不是由意志决定的,而是引起问题的。

它只能在case部分没有语句的情况下使用,例如:

switch (whatever)
{
    case 1:
    case 2:
    case 3: boo; break;
}

在每个case语句之后需要break或goto语句,即使它是默认的case。

开关失效在历史上是现代软件的主要漏洞来源之一。语言设计人员决定强制在case的末尾跳转,除非您默认直接跳转到下一个case而不进行处理。

switch(value)
{
    case 1:// this is still legal
    case 2:
}