Closed JFMous closed 7 years ago
Case guards in pattern matching #206 will open this up to allowing for arbitrary conditions:
int iq = DoIqTest();
switch (iq)
{
case * when iq <= 69:
ProcedureExtremelyLow();
break;
case * when iq <= 79:
BorderlineProcedure();
break;
case * when iq <= 89
LowAverageProcedure();
break;
case * when iq == 100:
ExactlyMedianProcedure();
break;
case * when iq <= 109:
AverageProcedure();
break;
case * when iq <= 119:
HighAverageProcedure();
break;
case * when iq <= 129:
SuperiorProcedure();
break;
default:
VerySuperiorProcedure();
break;
}
The wildcard pattern would match on anything but then the case guard would contain the specific conditions. They would be evaluated in lexical order.
would it make sense to make case
optional or perhaps switch expression?
switch {
when id <= 69: ... break;
...
}
might be preferrable over if else.
@alrz I like that somewhat, feels like a reasonable simplification.
But I feel this may be even more useful in pattern matching. In match expressions, the roughly equivalent form might be:
var x = match
{
when iq <= 69: ProcedureExtremelyLow(),
when iq <= 79: BorderlineProcedure(),
when iq <= 89: LowAverageProcedure(),
when iq <= 99 || (iq <= 109 && iq >= 101): AverageProcedure(),
when iq == 100: ExactlyMedianProcedure(),
when iq <= 119: HighAverageProcedure(),
when iq <= 129: SuperiorProcedure(),
default: VerySuperiorProcedure()
};
I like the possibilities but if iq
is always the comparison, it really feels like it should be the subject of the match expression. Something like the following feels more like pattern matching (although it would require a bit of rethinking what a relational expression is):
var x = iq match
{
when <= 69: ProcedureExtremelyLow(),
when <= 79: BorderlineProcedure(),
when <= 89: LowAverageProcedure(),
when == 100: ExactlyMedianProcedure(),
when <= 109: AverageProcedure(),
when <= 119: HighAverageProcedure(),
when <= 129: SuperiorProcedure(),
default: VerySuperiorProcedure()
};
And I'm not sure I like changing
when iq <= 99 || (iq <= 109 && iq >= 101):
into something like
when <= 99 || (<= 109 && >= 101):
@bondsbw, @JFMous : I would like to see something like the following implemented with the match
-pattern:
Func<int, string> func1, func2, func3, ...;
int iq = ...;
string result = iq match
{
when <= 100: func1,
when == 100: func2,
when >= 100: func3,
// ....
default: funcx()
}(iq);
Meaning, the possibility to use the match-statement inside of expressions.
@Unknown6656 The proposal is that match
is an expression, so of course you'd be able to use it within other expressions. You can think of it like a ternary op on steroids.
As for your specific example, there have been no proposed range patterns. Nor has there been a proposal to allow for only case guards with an implied wildcard pattern. So as of now your example would be:
string result = iq match (
case * when iq < 100: func1,
case * when iq == 100: func2,
case * when iq > 100: func3,
case *: funcx
)(iq);
Issue moved to dotnet/csharplang #812 via ZenHub
It would be nice if the case labels in switch statement supported comparison operators, much like the Select Case statement in Visual Basic does.
Now, there are only two options for the switch labels:
This could be extended to:
So you could write code as in this example:
The 'to' keyword would be used to specify a range. In the statement
switch (value)
,case x to y:
would be equivalent to the boolean expressionvalue >= x && value <= y