-1

This is part of the code, it gets a line of numbers from a textfile and counts how many numbers fit in each specified range. I'm converting it from if, else if statements (which works fine) just for practice. However none of the numbers are counting except 1, the highest number in the textfile, which fits in the default of this switch. Where did I go wrong?

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]);

this is the code using if else if statements, works fine.

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]);           
Filburt
  • 17,626
  • 12
  • 64
  • 115
  • If you want to compare with a range instead of a single value stay with `if` or if you use at least C#7 you can use [switch when](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/when#when-in-a-switch-statement). – Tim Schmelter May 15 '21 at 17:36

3 Answers3

1

The switch statement compares the value in students[i].Grade with each integer, which is behind the word "case". So case 1: compares the students[i].Grade with 1 and that is never true. 2,3 and 4 does nobody have too, so it always goes in the default case. So switch expression here is not a good idea, because you can not catch interval in a "case"

PKCS12
  • 407
  • 15
  • 41
Basti291
  • 21
  • 5
1

if you use c# 7+ you can try this

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
    }
Serge
  • 40,935
  • 4
  • 18
  • 45
1

You can use a new C# 9.0 pattern matching feature allowing you to combine patterns with and 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;
}

But you can simplify the logic a bit. E.g. you don't have to test for grade >= 60, since the cases are evaluated in order and the case <= 59 has already been tested (this is true for the if-else solution as well)

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

Note that if Grade is an int then <= 59 is equivalent to < 60. I used the second one as it looks nicer.

Yet another simplification can be achieved with the new switch expression (C# 8.0):

int index = students[i].Grade switch {
    < 60 => 0,
    < 70 => 1,
    < 80 => 2,
    < 90 => 3,
    _ => 4
};
distributions[index] += 1;
Olivier Jacot-Descombes
  • 104,806
  • 13
  • 138
  • 188
  • case <= 59: Actually that was what I tried at first, however I got errors. Sergey's suggestion worked, perhaps it is because the lack of c#9 pattern. Interesting. I'm very new at this. – Walter Melon May 15 '21 at 17:48
  • I will see how to go about using the new pattern and trying it again. – Walter Melon May 15 '21 at 17:51