在我们的实际开发中已经会遇到可空类型,而在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#函数式编程之可选值的更多相关文章

  1. Scala - 快速学习08 - 函数式编程:高阶函数

    函数式编程的崛起 函数式编程中的“值不可变性”避免了对公共的可变状态进行同步访问控制的复杂问题,能够较好满足分布式并行编程的需求,适应大数据时代的到来. 函数是第一等公民 可以作为实参传递给另外一个函 ...

  2. javascript - Underscore 与 函数式编程

    <Javascript函数式编程 PDF> # csdn下载地址http://download.csdn.net/detail/tssxm/9713727 Underscore # git ...

  3. java8函数式编程实例

    什么是函数式编程 函数式编程是java8的一大特色,也就是将函数作为一个参数传递给指定方法.别人传的要么是基本数据类型,要么就是地址引用 ,我们要穿一个“动作”. Stream 说到函数式编程,就不得 ...

  4. C#函数式编程之惰性求值

    惰性求值 在开始介绍今天要讲的知识之前,我们想要理解严格求值策略和非严格求值策略之间的区别,这样我们才能够深有体会的明白为什么需要利用这个技术.首先需要说明的是C#语言小部分采用了非严格求值策略,大部 ...

  5. day03 函数基本语法及特性 2. 参数与局部变量 3. 返回值 嵌套函数 4.递归 5.匿名函数 6.函数式编程介绍 7.高阶函数 8.内置函数

    本节内容 1. 函数基本语法及特性 2. 参数与局部变量 3. 返回值 嵌套函数 4.递归 5.匿名函数 6.函数式编程介绍 7.高阶函数 8.内置函数 温故知新 1. 集合 主要作用: 去重 关系测 ...

  6. 用C++进行函数式编程

    http://www.programmer.com.cn/12717/   文 / John Carmack 译 / 王江平 <Quake>作者Carmack认为追求函数式的程序设计有着实 ...

  7. Python进阶:函数式编程实例(附代码)

    Python进阶:函数式编程实例(附代码) 上篇文章"几个小例子告诉你, 一行Python代码能干哪些事 -- 知乎专栏"中用到了一些列表解析.生成器.map.filter.lam ...

  8. Python核心编程读笔 10:函数和函数式编程

    第11章 函数和函数式编程 一 调用函数  1 关键字参数 def foo(x): foo_suite # presumably does some processing with 'x' 标准调用 ...

  9. 《JS权威指南学习总结--8.8 函数式编程和8.8.1使用函数处理数组》

    内容要点:    和Lisp.Haskell不同,JS并非函数式编程语言,但在JS中可以像操控对象一样操控函数,   也就是说可以在JS中应用函数式编程技术.ES5中的数组方法(诸如map()和red ...

随机推荐

  1. CS0012: 类型“System.Data.Objects.DataClasses.EntityObject”在未被引用的程序集中定义

    entity framework,没在view引用 实体对象时,一直没问题,引用后爆出这个错误来  CS0012: 类型"System.Data.Objects.DataClasses.En ...

  2. Maven pom.xml 配置说明: 打jar包不包括指定资源文件和.class xml,配置不跑testCase,建pom父子项目

    **maven如何配置打jar包时,一些class 或者资源文件不打进来,把classpath的xml文件打进jar <build> <!--针对资源文件--> <res ...

  3. c++内存分布

    http://www.oschina.net/translate/cpp-virtual-inheritance 编译器会加入一些代码, 指针的转换操作编译器会自动加偏移

  4. SQL Server 集合处理

    UNION ALL 返回两个结果集中所有的行,返回结果集中会存在重复行 UNION 返回两个结果集中去重的行,返回结果集中无重复行 INTERSECT 返回两个结果集都有的行,返回结果集中无重复行 E ...

  5. 总结JS 常用函数

    希望本文总结的内容能给各位看官带来焕然一新的感觉.另外,如果你们有什么值得推荐的js技巧,欢迎在评论中补充,我可以收纳在本文中. PS:此文档会持续新增内容. Ajax请求 jquery ajax函数 ...

  6. 【Java学习笔记】集合转数组---toArray()

    package p2; import java.util.ArrayList; import java.util.Arrays; import java.util.List; public class ...

  7. Zepto 实现checkbox全选与全不选状态切换

    最近项目里用到foundation,而foundation4默认集成了Zepto,很多轮子要重造,所以有了下面的代码. <script> /** * Muti-Checking-Toggl ...

  8. Lnux 16.04 VM下安装与汉化

    参考linux-公社: http://www.linuxidc.com/Linux/2016-04/130520.htm  U盘安装linux16.04 http://www.linuxidc.com ...

  9. STM32 GPIO外部中断总结

    一.STM32中断分组: STM32 的每一个GPIO都能配置成一个外部中断触发源,这点也是 STM32 的强大之处.STM32 通过根据引脚的序号不同将众多中断触发源分成不同的组,比如:PA0,PB ...

  10. iis6|iis7|配置URLRewriter|64位操作系统下|.net2.0|.net4.0|配置URLRewriter|Web.config配置详情

    想必很多ASP.NET的码友们在IIS配置伪静态被严重纠结过不止一次两次,本园主经过多次站点伪静态配置,总结了一下,IIS版本:IIS 6.IIS 7,服务器:Windows Server 2003. ...