写点什么

C# 6 与 VB 12 即将加入模式匹配

  • 2014-08-17
  • 本文字数:1249 字

    阅读完需:约 4 分钟

又有一种源自于函数式编程语言中的概念加入了 C#和 VB 的阵营,这就是被称为模式匹配(Pattern Matching)的特性。初看上去,模式匹配的作用类似于一段 switch/select 语句块,但它的功能要强大的多。

请注意:由于 VB 版本的规格说明现在还没有完成,因此这些示例主要都是来自于 C#中的模式匹配规格说明

is 或 Matches 操作符

.NET 中的模式匹配主要是通过“is/Matches”操作符支持的。这种还让人不太熟悉的操作符将一个类分解为多个组成部分。以下这个示例是基于在周二的新闻报道中所提到过的 Cartesian 记录类 http://www.infoq.com/news/2014/08/Record-Class (record class)的基础上创建的。

复制代码
public static bool operator is(Cartesian c, out double x, out double y)
x = c.X;
y = c.Y;
return true;
}

这个 is 操作符不仅限于在它的定义类中使用,以下这个示例以另一种方式定义了一个操作符,使它能够分解一个 Cartesian 对象,让它能够匹配一个 Polar 对象。

复制代码
public static class Polar {
public static bool operator is( Cartesian c, out double R, out double Theta)
{
R = Math.Sqrt(c.X*c.X + c.Y*c.Y);
Theta = Math.Atan2(c.Y, c.X);
return c.X != 0 || c.Y != 0;
}
}
var c = Cartesian(3, 4);
if (c is Polar(var R, *))
Console.WriteLine(R);

类型模式

最简单的模式是类型模式,它本质上就是尝试进行类型转换并同时赋给某个变量。以下是这种模式的一个示例:

复制代码
if (expr is Type v)
{ // code using v }

递归模式

多数模式都是作为递归模式的形式出现,意即它们是由较简单的模式所组成的。看一下这种模式的示例:

复制代码
var a = new Location(1, 2, 3); //x=1, y=2, z=3
if (a is Location(1, var y, *))

这个递归模式包括了一个常数模式,一个 var 模式和一个通配符模式。

常数模式

这个模式可以将一个属性与一个常数值进行匹配,常数匹配使用 object.Equals(left, right) 方法来判断两者是否匹配。

Var 模式

Var 模式是一定会匹配成功的,该模式对应的变量将会被赋值为调用该 is 操作符时所提供的值,而该变量的类型则是由该表达式所决定的静态类型。

通配符模式

通配符模式本质上来说就是 var 表达式,不过你不需要关心匹配的结果。

内部实现

让我们继续讨论一下这个 location 类的示例,编译器在编译阶段会进行以下几个步骤的处理:

  1. 创建变量 $x、$y 和 $z
  2. 调用 Location.is(a, out $x, out $y, out $z) 方法,并确认返回结果为 true
  3. 常数模式:检查 object.Equals($x, 1) 调用的结果
  4. Var 模式:将 $y 赋给 y
  5. 通配符模式:忽略 $z 变量

Switch/Select Case 语句块

Switch 语句块的功能将得到扩展,它将能够使用模式匹配特性。这实际上意味着你可以按以下方式编写语句:

复制代码
case null:
case String s
case Location(1, var y, *):

限制

在目前的规格草稿中,还没有对于范围检查的支持。这意味着你不能编写类似于“a is Location( > 0, 1 to 5, <= 10)”这样的代码。此外目前也不支持在一个列表或迭代器中进行元素匹配。

查看英文原文: Pattern Matching in C# 6 and VB 12

2014-08-17 01:402591
用户头像

发布了 428 篇内容, 共 191.7 次阅读, 收获喜欢 39 次。

关注

评论

发布
暂无评论
发现更多内容

Linux操作系统——用户管理、实用指令

胖虎不秃头

Linux 10月月更

react的jsx和React.createElement是什么关系?面试常问

beifeng1996

React

能否手写vue3响应式原理-面试进阶

helloworld1024fd

JavaScript

[架构实战] 课后作业二

爱学习的麦子

Linux操作系统——定时任务调度、磁盘分区与挂载、网络配置

胖虎不秃头

Linux 操作系统 10月月更

Vue3入门指北(六)列表渲染

Augus

Vue3 10月月更

Qt中读取json文件以及总结

中国好公民st

c++ qt 10月月更

【从0到1学算法】2.递归

Geek_65222d

10月月更

Linux操作系统——组管理和权限管理

胖虎不秃头

Linux 操作系统 10月月更

Python应用之计算阶乘

芯动大师

函数 10月月更 阶乘计算

怎样对react,hooks进行性能优化?

beifeng1996

React

SAP 电商云 Spartacus UI 的响应式 UI 实现细节

汪子熙

前端 前端开发 web开发 10月月更 breakpoint

2022-10-02:以下go语言代码能否通过编译?A: 能;B: 不能;C: 不知道。 package main import ( “fmt“ ) type worker interfa

福大大架构师每日一题

golang 福大大 选择题

业务实时监控服务

穿过生命散发芬芳

10月月更 业务监控

js事件循环与macro&micro任务队列-前端面试进阶

loveX001

JavaScript

【愚公系列】2022年10月 Go教学课程 016-运算符之逻辑运算符和其他运算符

愚公搬代码

10月月更

写过自定义指令吗,原理是什么?

bb_xiaxia1998

Vue

MyBatis 学习笔记之MyBatis入门开发

薛定谔的猫

mybatis 10月月更 mybatis入门

MyBatis 学习笔记之配置文件

薛定谔的猫

mybatis 10月月更 mybatis配置文件

如何在 Linux 中删除超过 30 天的文件

wljslmz

Linux 10月月更

Linux操作系统——日志管理

胖虎不秃头

Linux 操作系统 10月月更

【SSM】Spring系列——IoC 控制反转

胖虎不秃头

spring ssm 10月月更

架构师的十八般武艺:变更管理

agnostic

需求变更

架构师的十八般武艺:风险管理

agnostic

风险管理

用30分钟相中10倍工程师

愚夫一得

面试 技术管理 招聘 文化 & 方法

Docker下,两分钟极速体验Nacos

程序员欣宸

Docker Spring Cloud 10月月更

大数据ELK(十一):Elasticsearch架构原理

Lansonli

elasticsearch 10月月更

面试官:vue2和vue3的区别有哪些?

bb_xiaxia1998

Vue

Collections之 Arraylist源码解读(二)

知识浅谈

ArrayList 10月月更

【一Go到底】第二天---你好,Go and GOROOT&GOPATH

指剑

golang Go入门 10月月更

Linux操作系统——进程管理、RPM与YUM

胖虎不秃头

操作系统 Linux tar 10月月更

C# 6与VB 12即将加入模式匹配_C#_Jonathan Allen_InfoQ精选文章