可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
How does a switch-expression needs to be written to support multiple cases returning the same result?
With c# prior to version 8 a switch may be written like so:
var switchValue = 3;
var resultText = string.Empty;
switch (switchValue)
{
case 1:
case 2:
case 3:
resultText = "one to three";
break;
case 4:
resultText = "four";
break;
case 5:
resultText = "five";
break;
default:
resultText = "unkown";
break;
}
When I am using the c# version 8 expression syntax its like so:
var switchValue = 3;
var resultText = switchValue switch
{
1 => "one to three",
2 => "one to three",
3 => "one to three",
4 => "four",
5 => "five",
_ => "unknown",
};
So my question is: How to make the cases 1,2 and 3 to just one switch-case-arm so the value doesn`t need to be repeated?
Update per suggestion from "Rufus L":
For my given example this works.
var switchValue = 3;
var resultText = switchValue switch
{
var x when (x >= 1 && x <= 3) => "one to three",
4 => "four",
5 => "five",
_ => "unknown",
};
But its not exactly what I want to accomplish. This is still only one case (with a filter condition), not multiple cases yielding to the same right-hand result.
回答1:
I got around to installing it, but I have not found a way to specify multiple, separate case labels for a single switch section with the new syntax.
However, you can create a new variable that captures the value and then use a condition to represent the cases that should have the same result:
var resultText = switchValue switch
{
var x when
x == 1 ||
x == 2 ||
x == 3 => "one to three",
4 => "four",
5 => "five",
_ => "unknown",
};
This is actually more concise if you have many cases to test, because you can test a range of values in one line:
var resultText = switchValue switch
{
var x when x > 0 && x < 4 => "one to three",
4 => "four",
5 => "five",
_ => "unknown",
};
回答2:
Sadly, this appears to be a shortcoming in the switch-expression syntax, relative to the switch-statement syntax. As other posters have suggested, the rather clumsy var
syntax is your only real option.
So you might have been hoping you could write:
switchValue switch {
Type1 t1:
Type2 t2:
Type3 t3 => ResultA, // where the ResultX variables are placeholders for expressions.
Type4 t4 => ResultB,
Type5 t5 => ResultC
};
Instead you will need to write the rather awkward code below, with typename sprayed about:
switchValue switch {
var x when x is Type1 || x is Type2 || x is Type 3 => ResultA,
Type4 t4 => ResultB,
Type5 t5 => ResultC
};
In such a simple example, you can probably live with this awkwardness. But more complicated example are much less liveable with. In fact my examples are actually a simplification of an example drawn from our own code base, where I was hoping to convert a switch-statement, with roughly six outcomes but over a dozen type-cases, into a switch-expression. And the result was clearly less readable than the switch-statement.
My view is that if the switch-expression needs shared outcomes and is more than a few lines long, then you are better off sticking to a switch-statement. Boo! It's more verbose but probably a kindness to your teammates.
ResultType tmp;
switch (switchValue) {
case Type1 t1:
case Type2 t2:
case Type3 t3:
tmp = ResultA;
break;
case Type4 t4:
tmp = ResultB;
break;
case Type5 t5:
tmp = ResultC;
break;
};
return tmp;
回答3:
If your switch type is a flag enum
[System.Flags]
public enum Values
{
One = 1,
Two = 2,
Three = 4,
Four = 8,
OneToThree = One | Two | Three
}
var resultText = switchValue switch
{
var x when Values.OneToThree.HasFlag(x) => "one to three",
Values.Four => "4",
_ => "unknown",
};
回答4:
Try bool operators
var switchValue = 3;
var resultText = switchValue switch
{
1 | 2 | 3 => "one to three",
4 => "four",
5 => "five",
_ => "unknown",
};