[英]Can I simplify this C# 7 switch statement to not re-state the type?
I'm looking at C# 7's new switch statement, and while it's awesome that I can switch on the type as part of pattern matching, I wonder if I can avoid re-stating the type in case I already know it? 我正在看C#7的新switch语句,虽然我可以打开类型作为模式匹配的一部分很棒,但我想知道如果我已经知道它可以避免重新说明类型吗?
Example: 例:
private static void BetterSwitchCase(string s)
{
switch (s)
{
case string x when x.Length == 3 && int.TryParse(x, out int i):
Console.WriteLine($"s is a string that parses to {i}");
break;
default:
Console.WriteLine("No Match.");
break;
}
}
Here, my case statement re-states string x
even though the type I'm switching on is already a string, and I only care about it's Length
and if it int.TryParse
s. 在这里,我的case语句重新声明string x
即使我正在打开的类型已经是一个字符串,我只关心它的Length
,如果它是int.TryParse
s。
Just omitting it doesn't compile: 省略它不会编译:
// Syntax error, ':' expected
case when s.Length == 3 && int.TryParse(s, out int i):
// A constant value is expected
case s when s.Length == 3 && int.TryParse(s, out int i):
So I'm just wondering if there is a way to omit it, or if it's just part of the pattern matching syntax that I have to accept. 所以我只是想知道是否有一种方法可以省略它,或者它只是我必须接受的模式匹配语法的一部分。
You could use var
pattern: 你可以使用var
pattern:
case var x when x.Length == 3 && int.TryParse(x, out int i):
Or even better, var
pattern with a discard: 甚至更好, var
disc with discard:
case var _ when s.Length == 3 && int.TryParse(s, out int i):
No, you can't omit the type (or var
keyword masking the type), as it is a part of pattern matching here. 不,你不能省略类型(或var
关键字掩盖类型),因为它是模式匹配的一部分。
Consider class hierarchy (this will not compile in C#7
, but will compile in further versions after full implementation) 考虑类层次结构(这不会在C#7
编译,但在完全实现后将在其他版本中编译)
class Geometry();
class Triangle(int Width, int Height, int Base) : Geometry;
class Rectangle(int Width, int Height) : Geometry;
class Square(int width) : Geometry;
Now we get a variable like this: 现在我们得到一个这样的变量:
Geometry g = new Square(5);
Now we do the switch
over it: 现在我们switch
它:
using static System.Console;
switch (g)
{
// check that g is a Triangle and deconstruct it into local variables
case Triangle(int Width, int Height, int Base):
WriteLine($"{Width} {Height} {Base}");
break;
// same for Rectangle
case Rectangle(int Width, int Height):
WriteLine($"{Width} {Height}");
break;
// same for Square
case Square(int Width):
WriteLine($"{Width}");
break;
// no luck
default:
WriteLine("<other>");
break;
}
Back to your case, consider the code: 回到你的情况,考虑代码:
switch (s)
{
case string x when x.Length == 3 && int.TryParse(x, out int i):
Console.WriteLine($"s is a string that parses to {i}");
break;
// will not compile with error
// An expression of type string cannot be handled by a pattern of type int.
case int x:
break;
// will win pattern matching and print the line
// {s} is an object
case object x:
Console.WriteLine($"{s} is an object");
default:
Console.WriteLine("No Match.");
break;
}
So type checking is a part of pattern matching and you can't omit it (and for C#7
it's only available to switch on types, full support is planned for C#8
). 所以类型检查是模式匹配的一部分,你不能省略它(对于C#7
它只能用于打开类型,计划为C#8
全面支持)。 Example was brought from here . 示例来自这里 。 The previous step was the when
clause for exception handling in C#6
上一步是C#6
异常处理的when
子句
I've used the following. 我使用了以下内容。 Aesthetically it is displeasing, but it does have two advantages. 在美学上它令人不快,但它确实有两个优点。 It's fairly easy to understand and it compiles. 它很容易理解并且编译。 The x ends up not being used. x最终没有被使用。 The variable in the switch statement can be a dummy. switch语句中的变量可以是虚拟的。 If you have particularly complicated heavily nested if-then code this method can be used and can be easier to /read/understand. 如果您有特别复杂的嵌套if-then代码,则可以使用此方法,并且可以更容易/读取/理解。 Anyone know a better way? 谁知道更好的方法?
switch (dummyString)
{
case string x1 when word = "entry":
DoEntry();
break;
case string x2 when word = "exit" && door="front":
DoFrontDoorExit();
break;
case string x3 when word = "exit" && door="rear":
DoRearDoorExit();
break;
case string x4 when Tomorrow() == "Tuesday":
BuyALotteryTicket()
break;
default:
break;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.