C#8 的模式匹配实现

C# 7 里面的Pattern Mathing

更多内容请查看官方文档:https://docs.microsoft.com/zh-cn/dotnet/csharp/whats-new/csharp-8#more-patterns-in-more-places?WT.mc_id=DT-MVP-5003302

is 模式

switch 和 when

C# 8 里面的Pattern Matching

使用Deconstructor 和 位置匹配模式

下面两个类Teacher和Student都由构造函数(Constructor)和Deconstructor:

下面我想写一个方法判断学生是不是5年级并且是学数学的:

这里我们就用到了Student的Deconstructor和位置匹配模式,这里面的下划线叫做“discard”(丢弃),表示我们不会使用它不关心它。

如果代码这样写,那么传进来的任何学生都满足这个匹配。

如果想判断5年纪的学生,我们可以这样写:

还想判断他的老师是否教数学,可以这样写:

注意,这里面调用的都是Deconstructor。

实际上,我们可以把Deconstructor的类型去掉,像这样:

实际上针对这种需求,使用if语句可能更好,更容易维护。但是如果循环嵌套的情况下无法使用if,那么这种位置模式匹配就有用了。

属性匹配模式

位置匹配模式很强大,但是可阅读性太差,下面看看属性匹配模式。

还是之前的需求:

我想这个一看就明白,不需要解释了吧?

而且这个方法可以写的更通用一些:

参数类型改为object,然后先判断它是不是Student,在判断是否是5年级学数学的。

Swtich 表达式

有三个形状的类,它们的属性各不相同:

下面我要写一个方法,根据不同的形状,显式相应的信息。这里我会使用C# 8 的 switch表达式。

先从最简单的只有一种情况开始:

方法参数的类型是object,然后使用C# 8的switch表达式,该表达式有返回值,所以可以把返回值放到变量里面然后返回。

可以看到,switch表达式里面没有case 关键字,这里使用的是lambda表达式。

这句话的意思就是,如果shape是Rectangle类型的,那么我们可以通过r这个变量来访问它,右侧的字符串就是这个case表达式的值,这里的返回值就是一个字符串。

把三个形状都写上,就是这样:

注意,这里没有break或者return。并且switch表达式不支持“接盘”(fall through)。

那么默认情况怎么添加呢?这里我们使用discard匹配模式:

这里我们还可以使用属性匹配模式来设置过滤条件:

使用嵌套的switch表达式,也可以达到同样的目的:

最后我们可以让整个方法更简化一点,使用expression-bodied方法:

但还是不要过度使用这种嵌套的模式,毕竟人类还需要阅读你的代码。。。

元组匹配模式

先定义一个枚举:

然后写一个方法,传进两个颜色,得到混合后的颜色:

这里面用的就是元组匹配模式。

最下面还判断了两种颜色都一样的情况,以及其它所有情况。

更详细内容请查看官方文档:https://docs.microsoft.com/zh-cn/dotnet/csharp/whats-new/csharp-8#more-patterns-in-more-places?WT.mc_id=DT-MVP-5003302

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • C# 观察者模式实例介绍

    观察者模式 观察者模式:定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主体对象,这个主题对象在状态发生变化时,会通知所有观察者.当一个对象改变需要同时改变其他对象,而且他不知道具体有多少对象需要改变的时候,应该考虑使用观察者模式. 观察者结构图: 使用场景:老板回来通知员工需要进入工作状态. 定义观察者的抽象类: 复制代码 代码如下: abstract class Observer { protected string name; protected ISubject sub; pu

  • C#窗口实现单例模式的方法

    主要是应对这种需求:软件只允许启动一次. 将这个问题转化一下,可以这样描述:对于一个软件,在启动一个进程之后,不允许启动其它进程,如果第二次打开程序,就把已经启动的那个进程的窗口放到最前端显示. C# winfrom应用在启动之后会首先执行program.cs里的代码,所以需要在这里下手.启动后,检测是否有相同进程名的进程,如果有,就把那个进程的窗口提到前端,然后关闭自己. 用法:把你的program.cs改造成这个样子: static class Program { //windows api

  • 深入c#工厂模式的详解

    什么是工厂模式?类比生活中的概念,当我们需要打电话的时候,我们需要一部手机,我们通常会选择直接去卖手机的实体店买.但在程序设计中,当我们需要调用一个类(PhoneA或PhoneB)的方法的时候,我们往往还要关心他是怎么new出来的(见代码段1).这就好比我们自己还要去工厂里面告诉他们你要怎么生产出一部我需要的手机.而我们只关心他能不能打电话,你怎么做的关我屁事.所以这就有了工厂模式.工厂模式其实就是抽象出一个工厂,我需要什么手机,去哪个工厂买就行了.我不必关心他的制作过程,你只要能生产我要的功能

  • C#中正则表达式的3种匹配模式

    在C#中,我们一般使用Regex类来表示一个正则表达式.一般正则表达式引擎支持以下3种匹配模式:单行模式(Singleline).多行模式(Multiline)与忽略大小写(IgnoreCase). 1. 单行模式(Singleline) MSDN定义:更改点 (.) 的含义,使它与每一个字符匹配(而不是与除 \n 之外的每个字符匹配). 使用单行模式的典型场景是获取网页源码中的信息. 示例: 我们使用WebBrowser控件,从http://www.xxx.com/1.htm上获取了如下HTM

  • c#设计模式 适配器模式详细介绍

    后续内容将包括以下结构模式: 适配器模式(Adapter):Match interfaces of different classes合成模式(Composite):A tree structure of simple and composite objects装饰模式(Decorator):Add responsibilities to objects dynamically代理模式(Proxy):An object representing another object享元模式(Flywei

  • C#设计模式之单例模式实例讲解

    前言 最近开始花点心思研究下设计模式,主要还是让自己写的代码可重用性高.保证代码可靠性.所谓设计模式,我找了下定义:是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.毫无疑问,设计模式于己于他人于系统都是多赢的:设计模式使代码编制真正工程化:设计模式是软件工程的基石脉络,如同大厦的结构一样. 为什么要提倡"Design Pattern(设计模式)"? 根本原因是为了代码复用,增加可维护性.因此这次我们来学习下设计模式,最后会通过C#语言来实现这些设计模式作为例子,深刻

  • c# 代理模式

    代理模式的应用: 远程代理,为一个对象在不同的地址空间提供局部代表,可以隐藏一个对象存在于不同地质空间的事实. 虚拟代理,根据需要创建开销很大的对象,通过代理来存放实例化需要很长时间的真实对象. 安全代理,用来控制真实对象的访问权限. 智能代理,当调用代理时,可以代理处理一些额外的功能. 案例场景: 向一位自己心仪的女孩表达爱意,一般我们有两种选择:亲自出马(有自信的人)和 使用'媒婆'(比较害羞). 其中使用'媒婆'就是代理行为,我们实现如下: 调用代理模式的主函数: class Progra

  • C#模式画刷HatchBrush用法实例

    本文实例讲述了C#模式画刷HatchBrush用法.分享给大家供大家参考.具体如下: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using System.Drawing.Drawing2D; namespace

  • C#中的IDisposable模式用法详解

    本文实例讲述了C#中IDisposable模式的用法,针对垃圾资源的回收进行了较为详细的讲解.分享给大家供大家参考之用.具体方法如下: 首先,对于垃圾回收而言,在C#中,托管资源的垃圾回收是通过CLR的Garbage Collection来实现的,Garbage Collection会调用堆栈上对象的析构函数完成对象的释放工作:而对于一些非托管资源,比如数据库链接对象等,需要实现IDisposable接口进行手动的垃圾回收.那么什么时候使用Idisposable接口,以及如何使用呢? 先来参考一

  • Perl中的模式匹配学习笔记

    一.简介 模式指在字符串中寻找的特定序列的字符,由反斜线包含:/def/即模式def.其用法如结合函数split将字符串用某模式分成多个单词:@array = split(/ /, $line); 二.匹配操作符 =~.!~ =~检验匹配是否成功:$result = $var =~ /abc/;若在该字符串中找到了该模式,则返回非零值,即true,不匹配则返回0,即false.!~则相反.这两个操作符适于条件控制中,如: 复制代码 代码如下: if ($question =~ /please/)

  • Erlang中的模块与模式匹配介绍

    模块是Erlang的基本代码单元,erl文件编译后以.beam作为扩展名,采用UTF8字符集,.erl文件示意如下: -module(模块名,与存放模块的文件名相同) -export([方法名/输入参数的个数]) 复制代码 代码如下: Method1( {a,b,c})->a*b*c; Mehtod2({d,e})->d-e. 模块属性有两种类型:预定义型和用户定义型.   Erlang中用于代表函数的数据类型被称为fun,相当于python中的lambda,一般用于 1)      对列表里

  • Lua中的string库和强大的模式匹配学习笔记

    lua原生解释器对字符串的处理能力是十分有限的,强大的字符串操作能力来自于string库.lua的string函数导出在string module中.在lua5.1,同时也作为string类型的成员方法,因此,我们既可以写成string.upper(s), 也可以s:upper(),选择你喜欢的写法. string.len(s)返回s的长度. string.rep(s, n)返回重复s字符串n次的字符串. string.lower(s)返回一份已将大写转成小写的字符串s的拷贝 lower,upp

  • Lua字符串模式匹配函数小结

    模式匹配函数 在string库中功能最强大的函数是: 复制代码 代码如下: string.find(字符串查找) string.gsub(全局字符串替换) string.gfind(全局字符串查找) string.gmatch(返回查找到字符串的迭代器) 这些函数都是基于模式匹配的.与其他脚本语言不同的是,Lua并不使用POSIX规范的正则表达式[4](也写作regexp)来进行模式匹配.主要的原因出于程序大小方面的考虑:实现一个典型的符合POSIX标准的regexp大概需要4000行代码,这比

  • MySQL 字符串模式匹配 扩展正则表达式模式匹配

    标准的SQL模式匹配 SQL的模式匹配允许你使用"_"匹配任何单个字符,而"%"匹配任意数目字符(包括零个字符).在 MySQL中,SQL的模式缺省是忽略大小写的.下面显示一些例子.注意在你使用SQL模式时,你不能使用=或!=:而使用LIKE或NOT LIKE比较操作符. 例如,在表pet中,为了找出以"b"开头的名字: mysql> SELECT * FROM pet WHERE name LIKE "b%"; +--

  • php正则表达式中的非贪婪模式匹配

    一般情况下,正则表达式的匹配是贪婪模式的,比如下面这个例子: 字符串:....src="http://www.bloghome.cn/1.mp3" type="application/x-mplayer2" .... 要求的结果:http://www.bloghome.cn/1.mp3 如果匹配表达式写为:/src="(.*)"/,则得不到正确的结果,因为最后一个双引号的匹配是贪婪模式的. 解决办法:匹配表达式写为: /src="(.*

  • 正则表达式模式匹配的String方法

    在JavaScript代码中使用正则表达式进行模式匹配经常会用到String对象和RegExp对象的一些方法,例如replace.match.search等方法,以下是对一些方法使用的总结. String对象中支持正则表达式有4种方法,分别是:search.replace.match.split str.search(regexp) 定义:search()方法将在字符串str中检索与表达式regexp相匹配的字串,并且返回第一个匹配字串的第一个字符的位置.如果没有找到任何匹配的字串,则返回-1.

  • perl 模式匹配参数详解

    一.简介   模式指在字符串中寻找的特定序列的字符,由反斜线包含:/def/即模式def.其用法如结合函数split将字符串用某模式分成多个单词:@array = split(/ /, $line);二.匹配操作符 =~.!~   =~检验匹配是否成功:$result = $var =~ /abc/;若在该字符串中找到了该模式,则返回非零值,即true,不匹配则返回0,即false.!~则相反.   这两个操作符适于条件控制中,如:   if ($question =~ /please/) { 

  • Swift中switch语句区间和元组模式匹配

    废话不多说了,下面一段代码给大家介绍了switch语句区间和元组模式匹配,具体内容如下所示: // switch 的广义匹配 let x = 1000 // 也就是说并没有像C语言那样 要求 switch 后面的是整数常量 switch x { // case后面可以跟区间啦 case 1...9: print("个位数") case 10...99: print("十位数") case 100...999: print("百位数") case

  • 用JavaScript对JSON进行模式匹配(Part 1-设计)

    至于筛选条件的描述,模式匹配是一种很常见也很好用的方式.在 JavaScript 里面,用 JSON 来描述模式又是相当方便的事情,所以我们来做一个 JSON 模式匹配工具吧. 用例设计 作为一个 dispatcher ,我们只需要两个方法: notify 和 capture .一个最简单的用例是这样的: 复制代码 代码如下: Dispatcher.capture({ "status": 200, "command": "message" },

随机推荐