C#函数式编程之可选值
在我们的实际开发中已经会遇到可空类型,而在C#中自从2.0之后就提供了可空类型(Nullable<T>),普通的值类型是不可以赋值为NULL,但是在类型的后面加上问号就变成了可空类型,这样就可以赋值为NULL了。当然这样的方式也可以用于函数式编程中,但函数式编程有自己的独特方式来解决这种问题,今天我们将围绕这个问题,虽然篇幅比较少,但也请读者可以阅读完。
我们当然不能改变语言的设计,所以我们只能使用现有的来实现可选值。这里我们利用类来实现,下面是Option<T>初期的代码:
public sealed class Option<T>
{
private readonly T value;
public T Value
{
get
{
return value;
}
} private readonly bool hasValue;
public bool HasValue { get { return hasValue; } }
public bool IsSome { get { return hasValue; } }
public bool IsNone { get { return !hasValue; } } public Option(T value)
{
this.value = value;
this.hasValue = true;
} private Option() { }
public static readonly Option<T> None = new Option<T>();
}
这样我们就可以利用这个类来实现和可空类型一样的效果,比如下面这段代码:
var p1 = new Option<int>();
var p2 = Option<int>.None;
if (p1.HasValue) // 等价于 x != null
{ }
我们可以看到在实例化Option的时候还需要传递类型参数,这里我们可以通过一个技巧来避免输入类型参数,而依赖于类型推断,这里我们写个辅助类:
public sealed class Option
{
public static Option<T> Some<T>(T value)
{
return new Option<T>(value);
}
}
其实我们只是利用了一个泛型方法来创建这个实例就可以了,下面我们看看下面的示例:
static void Main(string[] args)
{
var p1 = Option.Some();
var p2 = Option.Some();
if (p1 == p2)
{
Console.WriteLine("Y");
}
Console.ReadKey();
}
这里我们看到Option.Some节省了一些功夫,但是读者如果运行上面这个例子会发现,“Y”并不会输出到控制台中,但是我们可以看到10本来就应该等于10。因为这里我们对比的是Option<T>类型,并且p1和p2是两个不同的Option<T>所以我们还需要加以改善,下面我们重载操作符(在Option<T>类中继续追加):
public static bool operator ==(Option<T> a, Option<T> b)
{
return a.HasValue == b.HasValue && EqualityComparer<T>.Default.Equals(a.Value, b.Value);
}
public static bool operator !=(Option<T> a, Option<T> b)
{
return !(a == b);
} public override int GetHashCode()
{
int hashCode = hasValue.GetHashCode();
if (hasValue)
hashCode ^= value.GetHashCode();
return hashCode;
}
这里我们通过重载“==”判断其中的Value,这样就可以解决上面的问题了。但是我们还有一个问题没有解决,就是在使用None的时候还需要传递类型参数,这里我们依然需要使用一个技巧来避免(在Option类中继续追加):
public static readonly Option None = new Option();
仅仅这样还不足够,因为Option无法转换成Option<T>类型所以我们还需要对Option<T>增加 功能,能够隐式的将Option转换成对应的Option<T>类型,下面是针对的代码(在Option<T>中增加):
public static implicit operator Option<T>(Option option)
{
return Option<T>.None;
}
这样我们就可以直接将Option与Option<T>进行对比了,到这里我们就完成了我们自己的可选值的实现,在具体的项目中是使用可空类型还是可选值完全可以根据你个人的喜好,笔者建议使用本节介绍的可选值。
C#函数式编程之可选值的更多相关文章
- Scala - 快速学习08 - 函数式编程:高阶函数
函数式编程的崛起 函数式编程中的“值不可变性”避免了对公共的可变状态进行同步访问控制的复杂问题,能够较好满足分布式并行编程的需求,适应大数据时代的到来. 函数是第一等公民 可以作为实参传递给另外一个函 ...
- javascript - Underscore 与 函数式编程
<Javascript函数式编程 PDF> # csdn下载地址http://download.csdn.net/detail/tssxm/9713727 Underscore # git ...
- java8函数式编程实例
什么是函数式编程 函数式编程是java8的一大特色,也就是将函数作为一个参数传递给指定方法.别人传的要么是基本数据类型,要么就是地址引用 ,我们要穿一个“动作”. Stream 说到函数式编程,就不得 ...
- C#函数式编程之惰性求值
惰性求值 在开始介绍今天要讲的知识之前,我们想要理解严格求值策略和非严格求值策略之间的区别,这样我们才能够深有体会的明白为什么需要利用这个技术.首先需要说明的是C#语言小部分采用了非严格求值策略,大部 ...
- day03 函数基本语法及特性 2. 参数与局部变量 3. 返回值 嵌套函数 4.递归 5.匿名函数 6.函数式编程介绍 7.高阶函数 8.内置函数
本节内容 1. 函数基本语法及特性 2. 参数与局部变量 3. 返回值 嵌套函数 4.递归 5.匿名函数 6.函数式编程介绍 7.高阶函数 8.内置函数 温故知新 1. 集合 主要作用: 去重 关系测 ...
- 用C++进行函数式编程
http://www.programmer.com.cn/12717/ 文 / John Carmack 译 / 王江平 <Quake>作者Carmack认为追求函数式的程序设计有着实 ...
- Python进阶:函数式编程实例(附代码)
Python进阶:函数式编程实例(附代码) 上篇文章"几个小例子告诉你, 一行Python代码能干哪些事 -- 知乎专栏"中用到了一些列表解析.生成器.map.filter.lam ...
- Python核心编程读笔 10:函数和函数式编程
第11章 函数和函数式编程 一 调用函数 1 关键字参数 def foo(x): foo_suite # presumably does some processing with 'x' 标准调用 ...
- 《JS权威指南学习总结--8.8 函数式编程和8.8.1使用函数处理数组》
内容要点: 和Lisp.Haskell不同,JS并非函数式编程语言,但在JS中可以像操控对象一样操控函数, 也就是说可以在JS中应用函数式编程技术.ES5中的数组方法(诸如map()和red ...
随机推荐
- 在Visual Studio 2012 Blue theme下使用Dark theme的文本编辑器颜色设置
Visual Studio 2012 默认提供了3种color theme: blue,light,和dark.其中dark的文本编辑器颜色设定很爽,可是整个菜单项加上一些小的窗口如Find Resu ...
- ubuntu下安装wordpress
网上大多都是说放在var/www下面 实际上新版的ubuntu默认放在 var/www/html 下面 当然这个配置是可以修改的
- B-Tree 学习
算法导论 第18章 B树与其他树的结构不同的是 B数是多叉而不是二叉树 而且分叉因子很大一般使用于数据库 针对需要硬盘IO的情况而使用 可以降低磁盘IOB树的一个节点是以磁盘的页面为单位,而不是数据 ...
- Sql Server 2008卸载后再次安装一直报错
sql server 2008卸载之后再次安装一直报错问题. 第一:由于上一次的卸载不干净,可参照百度完全卸载sql server2008 的方式 1. 用WindowsInstaller删除所有与S ...
- 将List转换为二维数组(result)
result的数据结构为List<Map<String,Object>> //将List转换为二维数组String[][] String[][] z = new String[ ...
- C#之方法的重载与递归
(1). 方法的重载:方法的名称相同,但参数不同. 1.如果参数的个数相同,那么参数的类型不能相同. 2.如果参数的类型相同,那么参数的个数不能相同. (2).方法的递归:方法自己调用自己.用于找出一 ...
- SaaS模式给用户带来的优势
这两年SaaS服务在中国越来越受欢迎,企业正在从使用本地化软件向SaaS服务转变.由于企业用户人力成本的上升.移动终端设备的兴起以及共享经济对企业的影响,企业采用经营设备.软件的方式也在逐渐发生着变化 ...
- 使用TFS 自动编译时的一点设置
MSBuild参数: /p:VisualStudioVersion=10.0 指定使用的VS编译版本
- oc数据类型
数据类型:基本数据类型.指针数据类型 基本数据类型:数值型.字符型(char).布尔型.空类型(void)指针数据类型:类(class).id数值型:整数类型int.浮点型float.doublec和 ...
- [C#基础]ref和out的使用
在C#中如果需要把值类型转换成引用类型传递其他方法中并使其原来值发生改变,使用 ref 和 out 转换成引用类型传递. 1. ref : 使用ref之前需要定义变量并初始化(必须初始) class ...