博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C# 中奇妙的函数–5. Nullable 静态类
阅读量:4879 次
发布时间:2019-06-11

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

前段时间忙于各处奔波没有写博,今天想和大家再来看看一个奇妙的函数。

首先假设你不得不处理一些已有的代码,里面用到了nullable(可空值类型)的变量, 你必须要用这变量与不可空变量比较.

使用  <, >, <=, >= 来比较 nullable 值

看下面的代码:

1: int? x = null;
2:
3: if (x < 100)
4: {
5:     Console.WriteLine("是, {0} 小于 100.",
6:                       x.HasValue ? x.ToString() : "null");
7: }
8: else
9: {
0:     Console.WriteLine("否, {0} 不小于 100.",
1:                       x.HasValue ? x.ToString() : "null");
2: }

有人可能认为要么结果为“是”, 要么 抛出 NullReferenceException, 对吗? 因为一个null的整型在我们理解中是比100小,但是运行的结果为“否”!

 

下面的例子更加的令人费解,因为结果也为“否”:

1: int? x = null;
2:
3: if (x < int.MaxValue)
4: {
5:     // ...
6: }

那么,我们说 null 小于所有的有效整型, 对吗? 如果对的话,你怎么看这段代码:

1: int? x = null;
2:
3: // 等等,X 不小于MinValue?
4: if (x < int.MinValue)
5: {
6:     // ...
7: }

如果我们使用大于符号判断时:

1: int? x = null;
2:
3: // x 也不大于MinValue….
4: if (x > int.MinValue)
5: {
6:     // ...
7: }

结果使用四种比较运算符 ( <, >, <=, >= ) 全都返回否。 这个同样适用于其他有这样运算符定义的类型: short,  float, double, DateTime, TimeSpan。

在.net 机制下 null 不是一个大数值,也不是小数值,比较时也不会发生异常。

 

更奇怪的事:

1: DateTime? x = null;
2: DateTime? y = null;
3:
4: if (x <= y)
5: {
6:     Console.WriteLine("你觉得他们相等吗?");
7: }
8: else
9: {
10:     Console.WriteLine("结果不是:<=, <, >, >= 根本不适用于null.");
11: }

再看看下面的代码:

1: int? x = null;
2: int? y = 100;
3:
4: if (x < y)
5: {
6:     Console.WriteLine("X 小于 Y");
7: }
8: else if (x > y)
9: {
10:     Console.WriteLine("X 大于 Y");
11: }
12: else
13: {
14:     // 这个才是我们得到的结果
15:     Console.WriteLine("X 等于 Y");
16: }
。。

解决方案: nullable 静态类

因此,我们已经看到,<,<=,>,>= 有一些有趣的意外行为。

但是,如果我们把null 看成是一个非常低的值应该怎么办?

例如,如果我们要排序一个列表。在列表中显示的是公司当前的股票价格:

 

代号      描述                                  价位

------      -----------------------    ----------
ABCZ        Apples and Oranges Inc     n/a
XYZP        Zippers and Buttons Inc    1.57
AZAZ        Carrots and Turnips Inc    23.13

 

比较运算符不适用于 null因此,我们不得不做一些非常复杂的逻辑,如:

1: if (x.HasValue)
 
2: {
 
3:     if (y.HasValue)
 
4:     {
 
5:         if (x < y)
 
6:         {
 
7:             Console.WriteLine("x < y");
 
8:         }
 
9:         else if (x > y)
 
0:         {
 
1:             Console.WriteLine("x > y");
 
2:         }
 
3:         else
 
4:         {
 
5:             Console.WriteLine("x == y");
 
6:         }
 
7:     }
 
8:     else
 
9:     {
 
0:         Console.WriteLine("x > y 因为 y 是 null, x 不是");
 
1:     }
 
2: }
 
3: else if (y.HasValue)
 
4: {
 
5:     Console.WriteLine("x < y 因为 x 是 null, y 不是");
 
6: }
 
7: else
 
8: {
 
9:     Console.WriteLine("x == y 因为 都为 null");
 
0: }

 

我们也许可以简化这个函数,但它仍然是相当凌乱!但有一个更清洁的方式做到这一点,

如果你在 读到 IComparer如何工作:

当使用 IComparable 时,允许将 Nothing 与任何类型进行比较,而且不会生成异常。 排序时,Nothing 被视为小于任何其他对象。

所以,我们可以改变我们的逻辑使用Nullable.Compare <T>( )静态方法 :

1: int? x = null;
 
2: int? y = 100;
 
3:
 
4: if (Nullable.Compare(x, y) < 0)
 
5: {
 
6:     //
 
7:     Console.WriteLine("x < y");
 
8: }
 
9: else if (Nullable.Compare(x, y) > 0)
 
0: {
 
1:     Console.WriteLine("x > y");
 
2: }
 
3: else
 
4: {
 
5:     Console.WriteLine("x == y");
 
6: }

摘要

所以,当比较两个数值而其中之一可能是一个null 时,考虑使用System.Nullable.Compare <T>( )方法,而不是比较运算符 。它会将 null 当作比任何值都小,而且使用它可以避免一些逻辑一致性问题,象 < 返回 false,>= 返回 true 等 。

更多精彩的相关文章,请阅读

本文参考翻译自

转载于:https://www.cnblogs.com/multiplesoftware/archive/2011/08/25/2152743.html

你可能感兴趣的文章
十二、网络编程——4-基于UDP协议的网络编程
查看>>
异常处理与调试6 - 零基础入门学习Delphi55(完)
查看>>
if语句三种形式
查看>>
正则表达式之字符串验证
查看>>
codeblocks如何支持_tmain?可移植代码的编码推荐
查看>>
省市联动 填坑
查看>>
canvas写的一个小时钟demo
查看>>
原来今天是冬至
查看>>
又混了一天班
查看>>
九度oj 1006
查看>>
HDU6400-2018ACM暑假多校联合训练1004-Parentheses Matrix-构造
查看>>
最短路问题专题
查看>>
《Redis复制与可扩展集群搭建》看后感
查看>>
Jquery Mobile总结
查看>>
223. Rectangle Area
查看>>
spring boot + velocity中文乱码解决方式
查看>>
读罢泪两行,人生成长必须面对的10个残酷事实
查看>>
ASP 32位程序运行与64位问题:ADODB.Connection 错误 '800a0ea9' 未指定提供程序,也没有指派的默认提供程序。...
查看>>
xcode-git笔记
查看>>
TCP和UDP的优缺点及区别
查看>>