C# 7给我们带来了一个半吊子的 switch 语句模式匹配,只能简单的匹配类型而已,完全没有什么用处。这里我提供个更好的简单实现,用 C# 6 的 ValueTuple 模拟函数式语言的模式匹配功能。

首先就是实现:

   public static class ValueTupleExtensions
{ /// <summary>
/// 至少匹配一个条件
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name=""></param>
/// <returns></returns>
public static TResult MatchOne<TResult>(params (Func<bool> condExpr, Func<TResult> resultExpr)[] pairs)
{
foreach (var pair in pairs)
{
if (pair.condExpr())
{
return pair.resultExpr();
}
}
throw new InvalidOperationException("无匹配的表达式");
} /// <summary>
/// 匹配默认或指定的条件
/// </summary>
/// <typeparam name="TResult"></typeparam>
/// <param name="defaultMatch"></param>
/// <param name="matchs"></param>
/// <returns></returns>
public static TResult MatchOneOrDefault<TResult>(
Func<TResult> defaultMatchExpr,
params (Func<bool> condExpr, Func<TResult> resultExpr)[] matchs)
{
foreach (var pair in matchs)
{
if (pair.condExpr())
{
return pair.resultExpr();
}
} return defaultMatchExpr();
} public static TOutput MatchOne<TInput, TOutput>(TInput inputValue, params (TInput matcheValue, Func<TOutput> resultValueExpr)[] pairs)
where TInput : IEquatable<TInput>
{
foreach (var pair in pairs)
{
if (inputValue.Equals(pair.matcheValue))
{
return pair.resultValueExpr();
}
} throw new InvalidOperationException("无匹配的值");
} public static TOutput MatchOneOrDefault<TInput, TOutput>(TInput inputValue, params (TInput matcheValue, Func<TOutput> resultValueExpr)[] pairs)
where TInput : IEquatable<TInput>
{
if (inputValue == null)
{
throw new ArgumentNullException(nameof(inputValue));
} foreach (var pair in pairs)
{
if (pair.matcheValue == null)
{
throw new ArgumentNullException(nameof(pairs));
} if (inputValue.Equals(pair.matcheValue))
{
return pair.resultValueExpr();
}
}
return default(TOutput);
}
}

然后用起来就非常简单了,首先使用 `using static` 引入静态函数:

using static ValueTupleExtensions;

然后我们实际操练下:

 class Program
{
static void Main(string[] args)
{
var a = ; //最简单的重载,与某个值相等就执行后面的 lambda 表达式
var matched = MatchOne(
a,
(, () => ""),
(, () => "")
); Console.WriteLine($"matched={matched}"); //更自由的形式,第一个 lambda 相当于 if
matched = MatchOne(
(() => a == , () => ""),
(() => a == , () => "")
); Console.WriteLine($"matched={matched}"); Console.ReadKey();
}
}

虽然括号略多,不过还是很好玩的吧。

Have fun!

C# 6 元组应用 Part 2:C# 也玩模式匹配的更多相关文章

  1. Scala中的元组

    元组 元组使用()表示的数据结构 元组使用()表示的数据结构 还可以使用模式匹配访问 使用场景非常有限,用于函数返回值不止1个的情况下 看代码: /** * 元组 * @author Administ ...

  2. 《快学Scala》——数组、映射和元组

    数组 定长数组:在Scala中可以用Array,初始化一个定长数组.例如: val nums = new Array[Int](10) //10个整数的数组,所有元素初始化为0 val a = new ...

  3. erlang程序设计--顺序编程

    erlang模块的基本结构 基本结构-module(filename).-export([funname/num]). c(filename). 编译erlang模块  .bean 结尾的文件 编译后 ...

  4. 代码演示C#各版本新功能

    代码演示C#各版本新功能 C#各版本新功能其实都能在官网搜到,但很少有人整理在一起,并通过非常简短的代码将每个新特性演示出来. 代码演示C#各版本新功能 C# 2.0版 - 2005 泛型 分部类型 ...

  5. python 数据类型 -- 元组

    元组其实是一种只读列表, 不能增,改, 只可以查询 对于不可变的信息将使用元组:例如数据连接配置 元组的两个方法: index, count >>> r = (1,1,2,3) &g ...

  6. 【.NET深呼吸】元组数据(Tuple)

    各位观众,大家好,欢迎收看由火星电视台直播的<老周吹牛>节目,注意:本节目没有任何技术含量,如果您没有兴趣,请砸掉电视机. 今天说一下System命名空间下的一个数据类型——Tuple,翻 ...

  7. python学习笔记(列表、元组、购物车实例)

    一.列表 列表和字典是最常用的两种数据类型 1. 需求:怎么存放班级80多人的姓名,如何实现? names = ["Zhangyang","Guyun",&qu ...

  8. python之最强王者(7)——元组(tuple)

    1.序列(sequence): 说明:在前面的字符串列表中其实我们已经用到了序列,之所以放到这篇来讲主要是为了承上启下,方便理解和记忆. python的数据访问模型:直接存取 ,序列 ,映射 对非容器 ...

  9. Python元组

    Python的元组与列表类似,不同之处在于元组的元素不能修改. 元组使用小括号,列表使用方括号. 元组创建很简单,只需要在括号中添加元素,并使用逗号隔开即可. 如下实例: tup1 = ('physi ...

随机推荐

  1. npm全局目录修改

    转载:http://www.qdfuns.com/notes/30749/0f66fcf5e62eed010f744d0d4adaa870.html 我之前安装npm时全是默认安装,模块全部安装在C盘 ...

  2. Javascript高级编程学习笔记(2)—— Script标签

    script标签 js在浏览器中的使用,肯定会涉及到script标签. 那么script标签有哪些属性呢? 1.async:异步加载(不让页面等待该脚本的加载执行,异步加载页面的其他部分) 2.cha ...

  3. Servlet案例4:用户注册

    数据库准备: CREATE DATABASE web; USE web; CREATE TABLE `user` ( `uid` ) NOT NULL, `username` ) DEFAULT NU ...

  4. CUDA driver version is insufficient for CUDA runtime version 解决

    配置ubuntu17.1+CUDA9.2的caffe环境,CUDA sample编译完成,执行到./deviceQuery时报错:CUDA driver version is insufficient ...

  5. web自动化测试(java)---测试过程中遇到的错误合集

    摸索测试,不管是安装.调测第一个用例都会遇到各种各样的问题,或是自己的问题或是程序本身设置问题 只有把所有问题记录下来,才对得起自己的经历 1.设置firefox的执行文件错误 Exception i ...

  6. Difference Between Session.run and Tensor.eval

    [Question]: TensorFlow has two ways to evaluate part of graph: Session.run on a list of variables an ...

  7. 【Java基本功】一文读懂final关键字的用法

    本文主要介绍了final关键字的基本使用方法及原理 final关键字可以修饰类.方法和引用. 修饰类,该类不能被继承.并且这个类的对象在堆中分配内存后地址不可变. 修饰方法,方法不能被子类重写. 修饰 ...

  8. Kafka项目实战-用户日志上报实时统计之编码实践

    1.概述 本课程的视频教程地址:<Kafka实战项目之编码实践>  该课程我以用户实时上报日志案例为基础,带着大家去完成各个KPI的编码工作,实现生产模块.消费模块,数据持久化,以及应用调 ...

  9. Docker数据卷容器备份、恢复

    1.备份数据卷容器 使用数据卷来备份数据,通过指定本地的一个文件路径,对应到容器中的路径,运行tar命令将重要的文件打包备份. $ cd /home/xm6f/dev $ docker run --v ...

  10. Kafka文件存储机制那些事

    Kafka是什么 Kafka是最初由Linkedin公司开发,是一个分布式.分区的.多副本的.多订阅者,基于zookeeper协调的分布式日志系统(也可以当做MQ系统),常见可以用于web/nginx ...