質問

I haven't a living clue how to write this in c#. I know how to do it in Delphi.

This is how I would do it in Delphi:

Case Total of
    80..100 : ShowMessage ('You got an A!');
    60..79  : ShowMessage ('You got a B!');
    50..59  : ShowMessage ('You got a C!');
    40..49  : ShowMessage ('You got a D!');
    0..39   : ShowMessage ('You got an E...');
  end;

I have read tutorials for this, but I wouldn't know how to use/write it in the way I need it.

Here's my version in c#:

switch (Total) //'Total' is a bunch of Integers divided together to get a Percentage
            {
             case 80..100: //Where 80% to 100% would achieve an A
            {
             MessageBox.Show("You got an A!");
            }
             case 60..79: //Where 60% to 79% would achieve a B
            {
             MessageBox.Show("You got a B!");
            }

Is this possible?

Thanks.

役に立ちましたか?

解決

To express a range in a switch / case statement in C# you have to manually list out the cases

switch (Total) {
  case 80:
  case 81: 
  ...
  case 100:
    MessageBox.Show("you got an A");
    break;
  ...
}

For large ranges such as this though it may be better to just use a series of if statements

if (Total >= 80 && Total <= 100) { 
   MessageBox.Show("you got an A");
} else if (Total >= 70) { 
   MessageBox.Show("you got a B");
}

他のヒント

C# does not have a particularly flexible switch statement. This is intentional, options are limited to ensure that code generation is fast. C# has never been a language that hides execution cost. Runtime implementation is through a jump table, indexed by the switch() expression. Very fast, but not very flexible.

The alternative is an explicit if/else if chain. The exact same code that a VB.NET or Delphi compiler generates, but written by hand. Not terribly pretty, but effective enough:

if (Total < 0 || Total > 100) throw new ArgumentException("Not a valid grade");
if      (Total >= 80) ShowMessage ('You got an A!');
else if (Total >= 60) ShowMessage ('You got a B!');
else if (Total >= 50) ShowMessage ('You got a C!');
else if (Total >= 40) ShowMessage ('You got a D!');
else                  ShowMessage ('You got an E...');

This now also shows the cost associated with the code, there can be up to 6 comparisons on the Total value. If speed is essential and the range is limited then consider switching to a lookup table, a Dictionary<>. Not necessary here, ShowMessage() is an expensive method.

If it is supposed to be a switch then it should be like this:

switch(Total)
{
     case 100:
     case 99:
     //...
     case 80:
         MessageBox.Show("You got an A!");
         break;

     case 79:
     // ...
}

If it is okay to use if-statements I would recommend to do it like this:

if (Total < 0)
{
}
else if (Total < 40)
    MessageBox.Show("You got an E...")
else if (Total < 50)
    MessageBox.Show("You got a D!");
else if (Total < 60)
// etc.

Hop you could use this answer.

AFAIK you can't do it natively in C# but if you want to do it with a switch, like you stated in your question, there is a workaround for that (for fixed ranges). Considering your interval of 20 by 20:

int interval= (value-1) / 20;
  switch (interval) 
 {
    case 0: // 1-20
         //Do stuffs
         break; 
    case 1: // 21-40
         //Do stuffs
         break; 
    // and so on
 }

A solution to solve your problem is to do it like this.

switch (Total)
{
case 1: case 2: case 3:          
    // Do Something
    break;
case 4: case 5: case 6: 
    // Do Something
    break;
default:
    // Do Something
    break;
}

Multiple Cases in Switch:

What about this?:

var s = "EEEEDCBBAAA";
var result = s[Total/10];
MessageBox.Show("you got a " + result);

Because Switch Statements Smells :)

Update

Didn't realize the a / an difference, but:

MessageBox.Show(string.Format("you got a{0} {1}", 
     result == "A" || result == "E" ? "n" : "", 
     result));

You could use a switch/case statement by creating a very long case statement or an extension method that turned a range of numbers into a constant. But it's probably easier to use an if/else block.

Personally, I like the readability of Enumerable.Range slightly over >= and <=. However, it is a slower operation because you're creating an enumerable of ints everytime you do a comparison. You'll probably on notice performance issues when you get in the tens of thousands of grads though.

if(Enumerable.Range(80,100).Contains(Total))
{
    MessageBox.Show("You got an A!");
}
else if(Enumerable.Range(60, 79).Contains(Total))
{
    MessageBox.Show("You got a B!");
}
else if(Enumerable.Range(50, 59).Contains(Total))
{
    MessageBox.Show("You got a C!");
}
else if(Enumerable.Range(40, 49).Contains(Total))
{
    MessageBox.Show("You got a D!");
}
else if(Enumerable.Range(0, 39).Contains(Total))
{
    MessageBox.Show("You got an E...");
}

Use an action lookup (like a command pattern)

static void Main(string[] args)
        {
            var theGrade = 89;
            var gradeLookup = new Dictionary<Func<int, bool>, Action>
                    { 
                        { x => x >= 90, () => ShowMessage("You got an A!") },
                        { x => x >= 80 && x < 90, () => ShowMessage("You got an B!") },
                    };

            gradeLookup.First(x => x.Key(theGrade)).Value();

            Console.ReadKey();
        }

        static void ShowMessage(string msg)
        {
            Console.WriteLine(msg);
        }

You can also simply divide by 10 to reduce the checks, but this would only work for some college scales:

 static void Main(string[] args)
        {
            var theGrade = 80;
            switch (theGrade / 10)
            {
                case 10:
                case 9:
                    ShowMessage("You got an A");
                    break;
                case 8:
                    ShowMessage("You got a B");
                    break;
                case 7:
                    ShowMessage("You got a C");
                    break;
                case 6:
                    ShowMessage("You got a D");
                    break;
                default:
                    ShowMessage("You got a F");
                    break;

            }

            Console.ReadKey();
        }

What about this code:

private string GetTotalCode(int total) {
  if (Total >= 80 && Total <= 100)
    return "A"
  if ...
}

and then simplify switch:

switch (GetTotalCode(Total)) {
  case "A": 
    MessageBox.Show("you got an A");
    break;
  ...
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top