博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C#函数式编程之可选值
阅读量:6573 次
发布时间:2019-06-24

本文共 3325 字,大约阅读时间需要 11 分钟。

      在我们的实际开发中已经会遇到可空类型,而在C#中自从2.0之后就提供了可空类型(Nullable<T>),普通的值类型是不可以赋值为NULL,但是在类型的后面加上问号就变成了可空类型,这样就可以赋值为NULL了。当然这样的方式也可以用于函数式编程中,但函数式编程有自己的独特方式来解决这种问题,今天我们将围绕这个问题,虽然篇幅比较少,但也请读者可以阅读完。

 

 

我们当然不能改变语言的设计,所以我们只能使用现有的来实现可选值。这里我们利用类来实现,下面是Option<T>初期的代码:

1         public sealed class Option
2 { 3 private readonly T value; 4 public T Value 5 { 6 get 7 { 8 return value; 9 }10 }11 12 private readonly bool hasValue;13 public bool HasValue { get { return hasValue; } }14 public bool IsSome { get { return hasValue; } }15 public bool IsNone { get { return !hasValue; } }16 17 public Option(T value)18 {19 this.value = value;20 this.hasValue = true;21 }22 23 private Option() { }24 public static readonly Option
None = new Option
();25 }

 

 

这样我们就可以利用这个类来实现和可空类型一样的效果,比如下面这段代码:

1             var p1 = new Option
(10);2 var p2 = Option
.None;3 if (p1.HasValue) // 等价于 x != null4 {5 6 }

我们可以看到在实例化Option的时候还需要传递类型参数,这里我们可以通过一个技巧来避免输入类型参数,而依赖于类型推断,这里我们写个辅助类:

1         public sealed class Option2         {3             public static Option
Some
(T value)4 {5 return new Option
(value);6 }7 }

 

其实我们只是利用了一个泛型方法来创建这个实例就可以了,下面我们看看下面的示例:

1         static void Main(string[] args) 2         { 3             var p1 = Option.Some(10); 4             var p2 = Option.Some(10); 5             if (p1 == p2) 6             { 7                 Console.WriteLine("Y"); 8             } 9             Console.ReadKey();10         }

 

     

      这里我们看到Option.Some节省了一些功夫,但是读者如果运行上面这个例子会发现,“Y”并不会输出到控制台中,但是我们可以看到10本来就应该等于10。因为这里我们对比的是Option<T>类型,并且p1和p2是两个不同的Option<T>所以我们还需要加以改善,下面我们重载操作符(在Option<T>类中继续追加):

1             public static bool operator ==(Option
a, Option
b) 2 { 3 return a.HasValue == b.HasValue && EqualityComparer
.Default.Equals(a.Value, b.Value); 4 } 5 public static bool operator !=(Option
a, Option
b) 6 { 7 return !(a == b); 8 } 9 10 public override int GetHashCode()11 {12 int hashCode = hasValue.GetHashCode();13 if (hasValue)14 hashCode ^= value.GetHashCode();15 return hashCode;16 }

 

 

      这里我们通过重载“==”判断其中的Value,这样就可以解决上面的问题了。但是我们还有一个问题没有解决,就是在使用None的时候还需要传递类型参数,这里我们依然需要使用一个技巧来避免(在Option类中继续追加):

public static readonly Option None = new Option();

 

 

      仅仅这样还不足够,因为Option无法转换成Option<T>类型所以我们还需要对Option<T>增加 功能,能够隐式的将Option转换成对应的Option<T>类型,下面是针对的代码(在Option<T>中增加):

1             public static implicit operator Option
(Option option)2 {3 return Option
.None;4 }

 

这样我们就可以直接将Option与Option<T>进行对比了,到这里我们就完成了我们自己的可选值的实现,在具体的项目中是使用可空类型还是可选值完全可以根据你个人的喜好,笔者建议使用本节介绍的可选值。

 

转载地址:http://twljo.baihongyu.com/

你可能感兴趣的文章
Enhanced VMotion Compatibility (EVC) 功能介绍和实战设置
查看>>
RabbitMQ 流控制学习
查看>>
Ubuntu16.04 ssh安及root登录
查看>>
一个工程两个target
查看>>
linux 给文件夹权限
查看>>
用复制mysql/data 文件夹 下面的数据库的形式来复制数据库出现的问题
查看>>
C语言dos程序源代码分享(进制转换器)
查看>>
php项目中常用的log日志记录方法
查看>>
Android--实现点击一次返回键返回桌面而不是退出应用
查看>>
LogParser 导入MSSQL
查看>>
左侧固定导航栏
查看>>
linux安装go环境并编写第一个go程序
查看>>
解决:laravel出现Please provide a valid cache path.
查看>>
[JAVA] String常用方法
查看>>
oracle
查看>>
兼容IE浏览器样式的html上传文件控件
查看>>
直接插入排序
查看>>
fstab中mount错误导致不能启动
查看>>
OSPF转发地址深入解析
查看>>
SQLServer的Top功能
查看>>