Reputation: 698
I'm experimenting with switch statement pattern matching, and I'm looking for a way to return false if either value in a two value tuple is zero. This is the code I'm trying:
static bool IsAnyValueZero((decimal, decimal) aTuple)
{
switch(aTuple)
{
case (decimal, decimal) t when t.Item1 == 0 || t.Item2 == 0:
return true;
}
return false;
}
In VSCode 1.47 and dotnetcore 3.14 I get a compile-time error:
CS8652: The feature 'type pattern' is in Preview`
What is the best compatible way to write this code?
Upvotes: 8
Views: 8042
Reputation: 5213
Type pattern
in C# 8
does not support matching against tuple type in the form (decimal, decimal) t
. But we can match against tuple type by specifying type ValueTuple
that is used to represent tuples in C#
:
public static bool IsAnyValueZero((decimal, decimal) aTuple)
{
switch (aTuple)
{
case ValueTuple<decimal, decimal> t when t.Item1 == 0 || t.Item2 == 0:
return true;
}
return false;
}
Here is demo.
Another way to write your code is to use tuple pattern
:
public static bool IsAnyValueZero((decimal, decimal) aTuple)
{
switch (aTuple)
{
case (decimal i1, decimal i2) when i1 == 0 || i2 == 0:
return true;
}
return false;
}
Or we can rewrite this code the next way:
public static bool IsAnyValueZero((decimal, decimal) aTuple)
{
switch (aTuple)
{
// Discards (underscores) are required in C# 8. In C# 9 we will
// be able to write this case without discards.
// See https://github.com/dotnet/csharplang/blob/master/proposals/csharp-9.0/patterns3.md#type-patterns.
case (decimal _, decimal _) t when t.Item1 == 0 || t.Item2 == 0:
return true;
}
return false;
}
Also we can specify matching values explicitly:
public static bool IsAnyValueZero((decimal, decimal) aTuple)
{
switch (aTuple)
{
case (0, _):
return true;
case (_, 0):
return true;
}
return false;
}
Here is demo.
C# 9
adds improvements to type pattern
so that we will be able to match against tuple type using the next syntax (as in your original code sample):
switch (aTuple)
{
// In C# 9 discards (underscores) are not required.
case (decimal, decimal) t when t.Item1 == 0 || t.Item2 == 0:
return true;
}
This feature is in C# 9 preview
and it can be enabled.
Upvotes: 15