Преобразование операторов if в switch, но не работает, где преобразование пошло не так?

Это часть кода, он получает строку чисел из текстового файла и подсчитывает, сколько чисел помещается в каждый указанный диапазон. Я конвертирую его из операторов if, else if (которые отлично работают) просто для практики. Однако ни одно из чисел не считается, кроме 1, самого большого числа в текстовом файле, которое соответствует значению по умолчанию для этого переключателя. Где я ошибся?

int i = 0;

switch (students[i].Grade)
{
    case 1:
    {
        if(students[i].Grade <= 59) 
            distributions[0] += 1;
        break;
    }
    case 2:
    {
        if(students[i].Grade >= 60 && students[i].Grade <= 69)
            distributions[1] += 1;
        break;
    }
    case 3:
    {
        if(students[i].Grade >= 70 && students[i].Grade <= 79)
            distributions[2] += 1;
        break;
    }
    case 4:
    {
        if (students[i].Grade >= 80 && students[i].Grade <= 89)
            distributions[3] += 1;
        break;
    }
    // students with grade of 90 or above
    default:
    {
        distributions[4] += 1;
        break;
    }
}

Console.WriteLine("0-59: {0}\n60-69: {1}\n70-79: {2}\n80-89: {3}\n90-100: {4}", distributions[0], distributions[1], distributions[2], distributions[3], distributions[4]);

это код, использующий операторы if else if, работает нормально.

for (int i = 0; i < students.Length; i++)
  
    if (students[i].Grade <= 59)
    {
        distributions[0] += 1;
    }
    else if (students[i].Grade >= 60 && students[i].Grade <= 69)
    {
        distributions[1] += 1;
    }
    else if (students[i].Grade >= 70 && students[i].Grade <= 79)
    {
        distributions[2] += 1;
    }
    else if (students[i].Grade >= 80 && students[i].Grade <= 89)
    {
        distributions[3] += 1;
    }
    //students with grade of 90 or above
    else
    {
        distributions[4] += 1;
    }

Console.WriteLine("0-59: {0}\n60-69: {1}\n70-79: {2}\n80-89: {3}\n90-100: {4}", distributions[0], distributions[1], distributions[2], distributions[3], distributions[4]);           

person Walter Melon    schedule 15.05.2021    source источник
comment
Если вы хотите сравнить с диапазоном вместо одного значения, оставайтесь с if или если вы используете хотя бы C # 7, вы можете использовать переключить, когда.   -  person Tim Schmelter    schedule 15.05.2021


Ответы (3)


если вы используете С # 7+, вы можете попробовать это

for (int i = 0; i < students.Length; i++) 
switch (students[i].Grade)
    {
        case int n when (n <=59):
            distributions[0] += 1;
      break;
      
        case int n when (n >= 60 && n <= 69):
            distributions[1] += 1;
            break;

        .... and so on
    }
person Serge    schedule 15.05.2021

Оператор switch сравнивает значение в students[i].Grade с каждым целым числом, стоящим за регистром слова. Итак, случай 1: сравнивает students[i].Grade с 1, и это никогда не верно. _4 _, _ 5_ и 4 тоже никого не имеет, так что всегда идет по умолчанию. Поэтому выражение switch здесь не очень хорошая идея, потому что вы не можете поймать интервал в случае

person Basti291    schedule 15.05.2021

Вы можете использовать новую функцию сопоставления шаблонов C # 9.0, позволяющую комбинировать шаблоны с and и or

switch (students[i].Grade) {
    case <= 59:
        distributions[0] += 1;
        break;
    case >= 60 and <= 69:
        distributions[1] += 1;
        break;
    case >= 70 and <= 79:
        distributions[2] += 1;
        break;
    case >= 80 and <= 89:
        distributions[3] += 1;
        break;
    default:
        distributions[4] += 1;
        break;
}

Но можно немного упростить логику. Например. вам не нужно тестировать на оценку ›= 60, так как случаи оцениваются по порядку, а case‹ = 59 уже был протестирован (это верно и для решения if-else)

switch (students[i].Grade) {
    case < 60:
        distributions[0] += 1;
        break;
    case < 70:
        distributions[1] += 1;
        break;
    case < 80:
        distributions[2] += 1;
        break;
    case < 90:
        distributions[3] += 1;
        break;
    default:
        distributions[4] += 1;
        break;
}

Обратите внимание, что если Grade - это int, то <= 59 эквивалентно < 60. Я использовал второй, так как он выглядит лучше.

Еще одно упрощение может быть достигнуто с помощью нового переключателя выражение (C # 8.0):

int index = students[i].Grade switch {
    < 60 => 0,
    < 70 => 1,
    < 80 => 2,
    < 90 => 3,
    _ => 4
};
distributions[index] += 1;
person Olivier Jacot-Descombes    schedule 15.05.2021
comment
case ‹= 59: На самом деле это было то, что я пробовал сначала, но у меня были ошибки. Предложение Сергея сработало, возможно, из-за отсутствия шаблона C # 9. Интересный. Я новичок в этом. - person Walter Melon; 15.05.2021
comment
Я посмотрю, как использовать новый шаблон и попробую еще раз. - person Walter Melon; 15.05.2021