Evaluate Expressions in Switch Statements in C#
C#Switch StatementC# 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:
...
}