C# 8.0中的模式匹配相对C# 7.0来说有了进一步的增强,对于如下类:
class Point
{
public int X { get; }
public int Y { get; }
public Point(int x, int y) => (X, Y) = (x, y);
public void Deconstruct(out int x, out int y) => (x, y) = (X, Y);
}
首先来看C# 7.0中一个经典的模式匹配示例:
static string Display(object o){ switch (o) { case Point p when p.X == 0 && p.Y == 0: return "origin"; case Point p: return $"({p.X}, {p.Y})"; default: return "unknown"; }}
在C# 8.0中,它有更加精简的写法。
Switch表达式
在C# 8.0中,可以利用新的switch方式成模式匹配:
static string Display(object o) => o switch{ Point p when p.X == 0 && p.Y == 0 => "origin", Point p => $"({p.X}, {p.Y})", _ => "unknown"};
它利用一条switch语句完成了模式匹配,第一样看上去要简洁一些。不过,它还有更多更简单的写法。
Property patterns
可以直接通过在属性上指定值作为判定条件,
static string Display(object o) => o switch{ Point { X: 0, Y: 0 } => "origin", Point p => $"({p.X}, {p.Y})", _ => "unknown"};
也可以将属性值传递出来。
static string Display(object o) => o switch{ Point { X: 0, Y: 0 } => "origin", Point { X: var x, Y: var y } => $"({x}, {y})", _ => "unknown"};
Positional patterns
利用解构函数,可以写出更加精简的表达式。
static string Display(object o) => o switch{ Point(0, 0) => "origin", Point(var x, var y) => $"({x}, {y})", _ => "unknown"};
如果没有类型转换,则可以写得更加简单了:
static string Display(Point o) => o switch{ (0, 0) => "origin", (var x, var y) => $"({x}, {y})"};
非空判断
如果只是判断空和非空,则有最简单的模式:
{ } => o.ToString(),null => "null"
Tuple patterns
也支持直接对ValueTuple进行模式匹配,用起来非常灵活。
static State ChangeState(State current, Transition transition, bool hasKey) => (current, transition, hasKey) switch{ (Opened, Close, _) => Closed, (Closed, Open, _) => Opened, (Closed, Lock, true) => Locked, (Locked, Unlock, true) => Closed, _ => throw new InvalidOperationException($"Invalid transition")};
小结
C# 8.0的模式匹配有了进一步的增强,虽然可以又有人要说是语法糖了,但用得好的话可以让你的代码逻辑简化不少,更加容易理解。
参考文章
Do more with patterns in C# 8.0
原文地址:https://www.cnblogs.com/TianFang/p/10322434.html
时间: 2024-10-09 15:55:30