[译]C#7 Pattern Matching
public struct Square
{
public double Side { get; }
public Square(double side)
{
Side = side;
}
}
public struct Circle
{
public double Radius { get; }
public Circle(double radius)
{
Radius = radius;
}
}
public struct Rectangle
{
public double Length { get; }
public double Height { get; }
public Rectangle(double length, double height)
{
Length = length;
Height = height;
}
}
public struct Triangle
{
public double Base { get; }
public double Height { get; }
public Triangle(double @base, double height)
{
Base = @base;
Height = height;
}
}
下面分别使用7之前的语法和7来写一个计算形状面积的方法。
is
类型模式表达式
在C# 7.0之前,我们需要使用if
和is
语句去判断类别:
public static double ComputeArea(object shape)
{
if (shape is Square)
{
var s = (Square)shape;
return s.Side * s.Side;
}
else if (shape is Circle)
{
var c = (Circle)shape;
return c.Radius * c.Radius * Math.PI;
}
// elided
throw new ArgumentException(
message: "shape is not a recognized shape",
paramName: nameof(shape));
}
在C# 7.0 中,通过使用is
表达式的扩展可以在类型判断成功的时候将其分配给一个变量,从而简化上面的代码:
public static double ComputeAreaModernIs(object shape)
{
if (shape is Square s)
return s.Side * s.Side; // s 只在这可用
else if (shape is Circle c)
return c.Radius * c.Radius * Math.PI; // c 只在这可用
else if (shape is Rectangle r)
return r.Height * r.Length; // r 只在这可用
// elided
throw new ArgumentException(
message: "shape is not a recognized shape",
paramName: nameof(shape));
}
新的is
表达式对值类型和引用类型都好使。
上面的例子中,变量s
、c
、r
只有在模式匹配表达式为true的时候才作用被分配。
通过switch语句使用模式匹配
之前switch
只支持常量模式。只能将变量和case
中的常量进行比较:
public static string GenerateMessage(params string[] parts)
{
switch (parts.Length)
{
case 0:
return "No elements to the input";
case 1:
return $"One element: {parts[0]}";
case 2:
return $"Two elements: {parts[0]}, {parts[1]}";
default:
return $"Many elements. Too many to write";
}
}
7之前switch
只支持常量模式。在C# 7.0 中没有这个限制了,可以通过switch
来使用类型模式:
public static double ComputeAreaModernSwitch(object shape)
{
switch (shape)
{
case Square s:
return s.Side * s.Side;
case Circle c:
return c.Radius * c.Radius * Math.PI;
case Rectangle r:
return r.Height * r.Length;
default:
throw new ArgumentException(
message: "shape is not a recognized shape",
paramName: nameof(shape));
}
}
在case
表达式中使用when
public static double ComputeArea_Version3(object shape)
{
switch (shape)
{
case Square s when s.Side == 0:
case Circle c when c.Radius == 0:
return 0;
case Square s:
return s.Side * s.Side;
case Circle c:
return c.Radius * c.Radius * Math.PI;
default:
throw new ArgumentException(
message: "shape is not a recognized shape",
paramName: nameof(shape));
}
}
在case
表达式中声明变量
static object CreateShape(string shapeDescription)
{
switch (shapeDescription)
{
case "circle":
return new Circle(2);
case "square":
return new Square(4);
case "large-circle":
return new Circle(12);
case var o when (o?.Trim()?.Length ?? 0) == 0:
// white space
return null;
default:
return "invalid shape description";
}
}
[译]C#7 Pattern Matching的更多相关文章
- Beginning Scala study note(5) Pattern Matching
The basic functional cornerstones of Scala: immutable data types, passing of functions as parameters ...
- Symbols of String Pattern Matching
Symbols of String Pattern Matching in Introduction to Algorithms. As it's important to be clear when ...
- scala pattern matching
scala语言的一大重要特性之一就是模式匹配.在我看来,这个怎么看都很像java语言中的switch语句,但是,这个仅仅只是像(因为有case关键字),他们毕竟是不同的东西,switch在java中, ...
- Zhu-Takaoka Two-dimensional Pattern Matching
Two dimensional pattern matching. Details may be added later.... Corresponding more work can be foun ...
- [PureScript] Break up Expressions into Cases in PureScript using Simple Pattern Matching
Pattern matching in functional programming languages is a way to break up expressions into individua ...
- [Scala] Pattern Matching(模式匹配)
Scala中的match, 比起以往使用的switch-case有著更強大的功能, 1. 傳統方法 def toYesOrNo(choice: Int): String = choice match ...
- pattern matching is C# 7.0
https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/is 原来的版本 private static s ...
- C#9.0 终于来了,带你一起解读Pattern matching 和 nint 两大新特性玩法
一:背景 1. 讲故事 上一篇跟大家聊到了Target-typed new 和 Lambda discard parameters,看博客园和公号里的阅读量都达到了新高,甚是欣慰,不管大家对新特性是多 ...
- 函数式编程之-模式匹配(Pattern matching)
模式匹配在F#是非常普遍的,用来对某个值进行分支匹配或流程控制. 模式匹配的基本用法 模式匹配通过match...with表达式来完成,一个完整的模式表达式长下面的样子: match [somethi ...
随机推荐
- [WC2010]重建计划(分数规划+点分治+单调队列)
题目大意:给定一棵树,求一条长度在L到R的一条路径,使得边权的平均值最大. 题解 树上路径最优化问题,不难想到点分治. 如果没有长度限制,我们可以套上01分数规划的模型,让所有边权减去mid,求一条路 ...
- SCOI2008着色方案(记忆化搜索)
有n个木块排成一行,从左到右依次编号为1~n.你有k种颜色的油漆,其中第i 种颜色的油漆足够涂ci 个木块.所有油漆刚好足够涂满所有木块,即 c1+c2+...+ck=n.相邻两个木块涂相同色显得很难 ...
- Arcgis for qml - 鼠标拖拽移动
以实现鼠标拖拽文本图层为例 GitHub:ArcGIS拖拽文本 作者:狐狸家的鱼 目的是利用鼠标进行拖拽. 实现两种模式,一种是屏幕上的拖拽,第二种是地图上图层的挪动. 屏幕上的拖拽其实跟ArcGIS ...
- 洛谷P4319 变化的道路
题意:给定图,每条边都有一段存在时间.求每段时间的最小生成树. 解:动态MST什么毒瘤...洛谷上还是蓝题... 线段树分治 + lct维护最小生成树. 对时间开线段树,每条边的存在时间在上面会对应到 ...
- CMakeLists.txt使用
背景:C++代码在编译的过程中需要进行文件的包含,该文主要介绍CMakeLists.txt相关语法 CMake之CMakeLists.txt编写入门
- (五)Oracle 的 oracle 表查询
http://www.hechaku.com/Oracle/oracle_tables_chack.html 通过scott用户下的表来演示如何使用select语句,接下来对emp.dept.salg ...
- 获取url中的参数并以对象的形式展示出来
速记:获取url中的参数并以对象的形式展示出来 function getUrlData(){ let url=window.location.search;//url中?之后的部分 console.l ...
- C# winform TreeView中关于checkbox选择的完美类[转]
http://www.cnblogs.com/kingangWang/archive/2011/08/15/2139119.html public static class TreeViewCheck ...
- io系列之常用流二
一.对象的序列化.持久化. 将java的对象的基本数据类型和图形存入文件中,实现对象数据的序列化和持久化. 操作对象可以使用: ObjectOutPutStream 和 ObjectInPutStre ...
- bzoj 2002: [Hnoi2010]Bounce 弹飞绵羊(分块算法)
传送门 题意: 中文题意,不再赘述. 题解: 下午在补分块算法的相关知识,看到某大神博客推荐的这道题目,就试着做了做: TLE了一下午可还行: 我的思路: 将这 n 个点分成 sqrt(n) 块: i ...