Несколько случаев в выражении switch - PullRequest
522 голосов
/ 16 сентября 2008

Есть ли способ пролистать несколько регистров без повторного ввода case value:?

Я знаю, что это работает:

switch (value)
{
   case 1:
   case 2:
   case 3:
      //do some stuff
      break;
   case 4:
   case 5:
   case 6:
      //do some different stuff
      break;
   default:
       //default stuff
      break;
}

но я бы хотел сделать что-то вроде этого:

switch (value)
{
   case 1,2,3:
      //Do Something
      break;
   case 4,5,6:
      //Do Something
      break;
   default:
      //Do the Default
      break;
}

Это синтаксис, о котором я думаю из другого языка, или я что-то упустил?

Ответы [ 15 ]

5 голосов
/ 16 сентября 2008

Один менее известный аспект switch в C # заключается в том, что он опирается на оператор = , и поскольку он может быть переопределен, вы можете получить что-то вроде этого:


string s = foo();

switch (s) {
  case "abc": /*...*/ break;
  case "def": /*...*/ break;
}
3 голосов
/ 08 сентября 2011

На самом деле мне тоже не нравится команда GOTO, но она есть в официальных материалах MS, здесь все допустимые синтаксисы.

Если достижима конечная точка списка операторов секции switch, возникает ошибка времени компиляции. Это известно как правило «не провалиться». Пример

switch (i) {
case 0:
   CaseZero();
   break;
case 1:
   CaseOne();
   break;
default:
   CaseOthers();
   break;
}

действительно, потому что ни у одной секции коммутатора нет достижимой конечной точки. В отличие от C и C ++, выполнение раздела переключателя не может «провалиться» до следующего раздела переключателя, и пример

switch (i) {
case 0:
   CaseZero();
case 1:
   CaseZeroOrOne();
default:
   CaseAny();
}

приводит к ошибке во время компиляции. Если за выполнением раздела переключателя следует выполнение другого раздела переключателя, необходимо использовать явный случай goto или оператор goto по умолчанию:

switch (i) {
case 0:
   CaseZero();
   goto case 1;
case 1:
   CaseZeroOrOne();
   goto default;
default:
   CaseAny();
   break;
}

Допускается использование нескольких меток в секции коммутации. Пример

switch (i) {
case 0:
   CaseZero();
   break;
case 1:
   CaseOne();
   break;
case 2:
default:
   CaseTwo();
   break;
}

Я полагаю, что в данном конкретном случае GOTO можно использовать, это фактически единственный путь к успеху.

источник: http://msdn.microsoft.com/en-us/library/aa664749%28v=vs.71%29.aspx

2 голосов
/ 23 февраля 2012

Кажется, что была проделана огромная работа по поиску способов получить один из наименее используемых синтаксисов C #, чтобы как-то выглядеть лучше или работать лучше. Лично я считаю, что оператор switch редко стоит использовать. Я настоятельно рекомендую проанализировать, какие данные вы тестируете, и какие конечные результаты вы хотите получить.

Скажем, например, что вы хотите быстро проверить значения в известном диапазоне, чтобы увидеть, являются ли они простыми числами. Вы хотите, чтобы ваш код не занимался расточительными вычислениями, и вы можете найти список простых чисел в диапазоне, который вы хотите, онлайн. Вы можете использовать массивный оператор switch для сравнения каждого значения с известными простыми числами.

Или вы можете просто создать массив карт простых чисел и получить немедленные результаты:

    bool[] Primes = new bool[] {
        false, false, true, true, false, true, false,    
        true, false, false, false, true, false, true,
        false,false,false,true,false,true,false};
    private void button1_Click(object sender, EventArgs e) {
        int Value = Convert.ToInt32(textBox1.Text);
        if ((Value >= 0) && (Value < Primes.Length)) {
            bool IsPrime = Primes[Value];
            textBox2.Text = IsPrime.ToString();
        }
    }

Может быть, вы хотите увидеть, является ли символ в строке шестнадцатеричным. Вы можете использовать некрасивый и несколько большой оператор switch.

Или вы можете использовать регулярные выражения для проверки символа или функцию IndexOf для поиска символа в строке известных шестнадцатеричных букв:

        private void textBox2_TextChanged(object sender, EventArgs e) {
        try {
            textBox1.Text = ("0123456789ABCDEFGabcdefg".IndexOf(textBox2.Text[0]) >= 0).ToString();
        } catch {
        }
    }

Допустим, вы хотите выполнить одно из 3 различных действий в зависимости от значения, которое будет находиться в диапазоне от 1 до 24. Я бы предложил использовать набор операторов IF. И если это стало слишком сложным (или числа были больше, например, 5 различных действий в зависимости от значения в диапазоне от 1 до 90), используйте перечисление для определения действий и создания карты массивов перечислений. Затем это значение будет использоваться для индексации в карте массива и получения перечисления нужного вам действия. Затем используйте небольшой набор операторов IF или очень простой оператор switch для обработки полученного значения перечисления.

Кроме того, хорошая вещь в карте массива, которая преобразует диапазон значений в действия, состоит в том, что она может быть легко изменена кодом. С помощью проводного кода вы не можете легко изменить поведение во время выполнения, но с картой массива это легко.

1 голос
/ 29 марта 2018

Если у вас очень большое количество строк (или любого другого типа), все делающие одно и то же, я рекомендую использовать список строк в сочетании со свойством string.Contains.

Итак, если у вас большой оператор switch, например:

switch (stringValue)
{
    case "cat":
    case "dog":
    case "string3":
    ...
    case "+1000 more string": //Too many string to write a case for all!
        //Do something;
    case "a lonely case"
        //Do something else;
    .
    .
    .
}

Возможно, вы захотите заменить его на выражение if, подобное этому:

//Define all the similar "case" string in a List
List<string> listString = new List<string>(){ "cat", "dog", "string3", "+1000 more string"};
//Use string.Contains to find what you are looking for
if (listString.Contains(stringValue))
{
    //Do something;
}
else
{
    //Then go back to a switch statement inside the else for the remaining cases if you really need to
}

Эта шкала хорошо подходит для любого числа строковых регистров.

0 голосов
/ 10 июля 2011

Для этого вы должны использовать оператор goto. Такие как:

    switch(value){
    case 1:
        goto case 3;
    case 2:
        goto case 3;
    case 3:
        DoCase123();
    //This would work too, but I'm not sure if it's slower
    case 4:
        goto case 5;
    case 5:
        goto case 6;
    case 6:
        goto case 7;
    case 7:
        DoCase4567();
    }
...