我可以简化此 C# 7 switch 语句以不重新声明类型吗?
Can I simplify this C# 7 switch statement to not re-state the type?
我正在查看 C# 7 的新 switch 语句,虽然我可以将类型作为模式匹配的一部分进行切换这很棒,但我想知道我是否可以避免重新声明该类型以防我已经知道它?
示例:
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;
}
}
在这里,我的 case 语句重新声明 string x
,即使我打开的类型已经是一个字符串,我只关心它是 Length
并且如果它是 int.TryParse
s.
只是省略它不会编译:
// 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):
所以我只是想知道是否有办法省略它,或者它是否只是我必须接受的模式匹配语法的一部分。
您可以使用 var
模式:
case var x when x.Length == 3 && int.TryParse(x, out int i):
甚至更好,var
带丢弃的模式:
case var _ when s.Length == 3 && int.TryParse(s, out int i):
不,您不能省略类型(或 var
关键字屏蔽类型),因为它是此处模式匹配的一部分。
考虑 class 层次结构(这不会在 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;
现在我们得到一个这样的变量:
Geometry g = new Square(5);
现在我们对其进行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;
}
回到你的案例,考虑代码:
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;
}
所以类型检查是模式匹配的一部分,你不能省略它(对于C#7
它只能用于打开类型,完全支持是计划 C#8
)。示例来自 here. The previous step was the when
clause for exception handling in C#6
我使用了以下内容。从美学上讲,它令人不快,但它确实有两个优点。它很容易理解并且可以编译。 x 最终未被使用。 switch 语句中的变量可以是虚拟变量。如果你有特别复杂的大量嵌套的 if-then 代码,可以使用这个方法并且可以更容易 /read/understand。有人知道更好的方法吗?
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;
}
我正在查看 C# 7 的新 switch 语句,虽然我可以将类型作为模式匹配的一部分进行切换这很棒,但我想知道我是否可以避免重新声明该类型以防我已经知道它?
示例:
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;
}
}
在这里,我的 case 语句重新声明 string x
,即使我打开的类型已经是一个字符串,我只关心它是 Length
并且如果它是 int.TryParse
s.
只是省略它不会编译:
// 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):
所以我只是想知道是否有办法省略它,或者它是否只是我必须接受的模式匹配语法的一部分。
您可以使用 var
模式:
case var x when x.Length == 3 && int.TryParse(x, out int i):
甚至更好,var
带丢弃的模式:
case var _ when s.Length == 3 && int.TryParse(s, out int i):
不,您不能省略类型(或 var
关键字屏蔽类型),因为它是此处模式匹配的一部分。
考虑 class 层次结构(这不会在 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;
现在我们得到一个这样的变量:
Geometry g = new Square(5);
现在我们对其进行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;
}
回到你的案例,考虑代码:
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;
}
所以类型检查是模式匹配的一部分,你不能省略它(对于C#7
它只能用于打开类型,完全支持是计划 C#8
)。示例来自 here. The previous step was the when
clause for exception handling in C#6
我使用了以下内容。从美学上讲,它令人不快,但它确实有两个优点。它很容易理解并且可以编译。 x 最终未被使用。 switch 语句中的变量可以是虚拟变量。如果你有特别复杂的大量嵌套的 if-then 代码,可以使用这个方法并且可以更容易 /read/understand。有人知道更好的方法吗?
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;
}