2天时间,聊今年最热的 Agent、上下文工程、AI 产品创新等话题。2025 年最后一场~ 了解详情
写点什么

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:402743
用户头像

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

关注

评论

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

助力直播平台源码脱颖而出,要完成哪些关键功能?

开源直播系统源码

软件开发 直播源码

测试开发【Mock平台】05开发:项目管理(一)后端接口

MegaQi

测试平台开发教程 6月月更 测试技术干货

6大优势、2种类型,一文吃透动态应用安全测试(DAST)

SEAL安全

DevOps 网络安全 DevSecOps 软件安全

面试突击57:聚簇索引=主键索引吗?

王磊

Java MySQL 面试

纯CSS 毛玻璃效果 💎

德育处主任

CSS 纯CSS 6月月更

使用 Prometheus 监控 SAP ABAP 应用程序

汪子熙

云计算 Kubernetes 云原生 abap 6月月更

手把手教学直播:如何提交 PR 成为龙蜥社区贡献者? | 第 23 期

OpenAnolis小助手

开源 PR 龙蜥社区 龙蜥大讲堂 社区贡献

NFT链游系统开发|NFT卡牌盲盒游戏

薇電13242772558

NFT 链游

Django 中的视图 | Python

海拥(haiyong.site)

Python django 6月月更

大数据培训Flink 简介与认知

@零度

flink 大数据开发

测试开发【Mock平台】04实战:前后端项目初始化与登录鉴权实现

MegaQi

测试平台开发教程 测试干货 6月月更

spring4.1.8扩展实战之五:改变bean的定义(BeanFactoryPostProcessor接口)

程序员欣宸

Java spring Spring Framework 6月月更

几个非常有用的 Flutter 技巧,你可以立即使用!

坚果

6月月更

C#入门系列(十六) -- 类及其成员介绍

陈言必行

C# 6月月更

Linux开发_Makefile规则与Shell脚本语言

DS小龙哥

6月月更

docker和docker compose安装使用、入门进阶案例

偶尔善良

Docker docker-co

企业知识管理就是信息化建设吗?

小炮

JavaScript异步函数async/await

大熊G

JavaScript 前端 6月月更

四次蝉联中国容器云市场TOP5!为应用赋能

BoCloud博云

云原生 容器技术 容器云 博云

MySQL索引

龙空白白

索引 MySQL InnoDB

安全服务厂商安全狗加入龙蜥社区

OpenAnolis小助手

开源 网络安全 龙蜥社区 龙腾计划 安全狗

实战 | Kibana面板使用

写程序的小王叔叔

Kibana ELK Stack 6月月更

【Python技能树共建】pyspider框架的使用

梦想橡皮擦

Python 6月月更

云原生技术 - 如何从代码到制作并发布一个 Helm 包?

孙健波

云原生 Helm

【愚公系列】2022年06月 通用职责分配原则(三)-低耦合原则

愚公搬代码

6月月更

InfoQ 极客传媒 15 周年庆征文| 手把手带你入门 API 开发

宇宙之一粟

flask-restful 6月月更 InfoQ极客传媒15周年庆 API开发

Paper Reading 预告 | Volcano-An Extensible and Parallel Query Evaluation System(众神推荐的 Paper 下载合集)

TiDB 社区干货传送门

TiDB Paper Reading

测试流程如何落地?

老张

软件测试 质量保障

InfoQ 极客传媒 15 周年庆征文|uni-app 路由传参参数丢失问题解决方案探究

No Silver Bullet

前端 6月月更 InfoQ极客传媒15周年庆 路由传参

Vone观点说|用DAO打造人类协作新形态

旺链科技

区块链 产业区块链 自组织协作

用 Golang 重写 rsync(3):C里面的谜之指针

老豆还编程

c

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