Evaluate Expressions in Switch Statements in C#

C#Switch Statement

C# Problem Overview


I have to implement the following in a switch statement:

switch(num)
{
  case 4:
    // some code ;
    break;
  case 3:
    // some code ;
    break;
  case 0:
    // some code ;
    break;
  case < 0:
    // some code ;
    break;
}

Is it possible to have the switch statement evaluate case < 0? If not, how could I do that?

C# Solutions


Solution 1 - C#

I know that this topic is pretty old but if someone still looking for the answer now in C# 7 it's possible. Here is an example:

switch (value)
{
     case var expression when value < 0:
         //some code
         break; 

     case var expression when (value >= 0 && value < 5):
         //some code
         break;

     default:
         //some code
         break;
}

Solution 2 - C#

Note: the answer below was written in 2009. Switch patterns were introduced in C# 7.


You can't - switch/case is only for individual values. If you want to specify conditions, you need an "if":

if (num < 0)
{
    ...
}
else
{
    switch(num)
    {
        case 0: // Code
        case 1: // Code
        case 2: // Code
        ...
    }
}

Solution 3 - C#

you can do this

switch (mark)
{
    case int n when n >= 80:
        Console.WriteLine("Grade is A");
        break;
	
    case int n when n >= 60:
        Console.WriteLine("Grade is B");
        break;
	
    case int n when n >= 40:
        Console.WriteLine("Grade is C");
        break;
	
    default:
        Console.WriteLine("Grade is D");
        break;
}

Solution 4 - C#

You could do something like this at the end of your switch statement:

default:
    if(num < 0)
    {
        ... // Code
    }
    break;

Solution 5 - C#

If your num can't be less than zero:

public int GetSwitch(int num) { return num < 0 ? -1 : num; }
switch(GetSwitch(num))
{
case 4: // some code ; break;
case 3:// some code ; break;
case 0: // some code ; break;
case -1 :// some code ; break;
}

If it can, use some other "non-existent" number such as int.MinValue.

Solution 6 - C#

In a twist of C# fate, this has come all the way back around. If you upgrade to C# 9.0, your original switch statement will now compile! C#9.0 has added Relational patterns to pattern matching in general, which includes switch statements.

You can now do some really funky stuff, like this:

      var num = new Random().Next();
      
      switch(num)
      {
        case < 0:
          // some code ;
          break;
        case 0:
          // some code ;
          break;
        case > 0 and < 10:
          // some code ;
          break;
        case > 20 or (< 20 and 15):
          // some code ;
          break;
      }

Note the use of literal 'and' and 'or' in the last case, to allow && and || type expressions to compile.

To use C# 9, make sure the XmlNode LangVersion is set to Latest or 9.0 in the csproj file, in a property group

e.g.

  <PropertyGroup>
    <TargetFramework>netstandard2.0</TargetFramework>
    <Platforms>AnyCPU;x86</Platforms>
    <Configurations>Debug;Release;Mock</Configurations>
	<LangVersion>Latest</LangVersion>
  </PropertyGroup>

Solution 7 - C#

Enter 2021.

var res = num switch
{
    4 => "It's four",
    3 => "It's three",
    0 => "It's zero",
    < 0 => "It's negative",
    _ => "It's something else"
};

Boom.

(To be fair, switch expressions are a C# 8.0 feature, so not really 2021. But still few people seem to know about it.)

Solution 8 - C#

You will have to use if, wether you want or not. Switch is only capable of comparing your value to constant values.

Solution 9 - C#

The only way I could think of (and I really don't recommand it), would be as follows:

int someValue;

switch (Math.Max(someValue, -1))
{
    case -1:
        // will be executed for everything lower than zero.
        break;

    case 0:
       // will be executed for value 0.
       break;

    case 1:
       // will be executed for value 1.
       break;

    default:
       // will be executed for anything else.
       break;
}

Solution 10 - C#

The other way around would be possible also (relating to Jon Skeet's answer):

switch(num)
{
  case a:
      break;
  default:
      if( num < 0 )
      {}
   break;
}

Solution 11 - C#

What you could do is to use a delegate like this.

		var actionSwitch = new Dictionary<Func<int, bool>, Action>
		{
			 { x => x < 0 ,		() => Log.Information("less than zero!")},
			 { x => x == 1,	    () => Log.Information("1")},
			 { x => x == 2,		() => Log.Information("2")},
			 { x => x == 3,		() => Log.Information("3")},
			 { x => x == 4,		() => Log.Information("4")},
			 { x => x == 5,	    () => Log.Information("5")},
		};

		int numberToCheck = 1;

        //Used like this
		actionSwitch.FirstOrDefault(sw => sw.Key(numberToCheck)).Value();

Just swap out what you wan´t to perform where the Log.Information("x") is and you have your "switch" statement.

You will need to some error handling if you check for a key that is "found" by the Func.

If you like to see the Func version of the switch I just wrote a blog post with Switch example chapter.

But if you can use C# 7 it will give you better switch capabilities.

Solution 12 - C#

You cannot use comparisons in switches like you could in VB, you have 2 options here, replace the value you switch on with a known value and use that or - if you mean all other cases - you can use the default clause:

switch(num)
{
  case 4:
    // some code ;
    break;
  case 3:
    // some code ;
    break;
  case 0:
    // some code ;
    break;
  default:
    // some code ;
    break;
}

Note that this does not exactly like you asked for: any values other than 0,3,4 will end up in the deafult: clause.

Solution 13 - C#

I've run into the following pattern recently, and while I abhor it, I can't argue that it's not practical:

switch(0)
{
  case 0 when x < 0:
    ...
    break;
  case 0 when a > 5 && x == 0:
    ...
    break;
}

The use of dummy expressions ((0) in the switch, and case 0) is absolutely terrible, and I'd hate for it to become an idiom, but hey - it's concise and very clear. For sure it's not some hack that completely obscures the meaning and needs arcane knowledge, but C# would do well to obviate the need for it. I'd like the following to be legal:

switch                   // maybe () here, if the grammar would demand
{
  case when x < 0:       // I like the case to stay
    ...
  case when a > 5 && x == 0:
    ...
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionpriyanka.sarkarView Question on Stackoverflow
Solution 1 - C#MaxView Answer on Stackoverflow
Solution 2 - C#Jon SkeetView Answer on Stackoverflow
Solution 3 - C#Cat_img.jpegView Answer on Stackoverflow
Solution 4 - C#tbreffniView Answer on Stackoverflow
Solution 5 - C#queen3View Answer on Stackoverflow
Solution 6 - C#Adam DiamentView Answer on Stackoverflow
Solution 7 - C#LeakyView Answer on Stackoverflow
Solution 8 - C#Maximilian MayerlView Answer on Stackoverflow
Solution 9 - C#Oliver HanappiView Answer on Stackoverflow
Solution 10 - C#StampedeXVView Answer on Stackoverflow
Solution 11 - C#SturlaView Answer on Stackoverflow
Solution 12 - C#rspView Answer on Stackoverflow
Solution 13 - C#Kuba hasn't forgotten MonicaView Answer on Stackoverflow