当你使用可空的值类型时,你会发现取值很不方便,比如Guid? obj,你要从obj中获取值,可以使用Value属性obj. Value,但obj可能为null,这时候就会抛出一个异常。

  可空值类型提供了一个HasValue属性,它可以识别出obj是不是一个null值,每当你获取可空值都需要加上这个判断if(value.HasValue){ var value = obj.Value;}。

  下面我们通过几个扩展方法,把判断封装起来。

  在Util项目中添加Extensions.Nullable.cs,代码如下。

  1. using System;
  2.  
  3. namespace Util {
  4. /// <summary>
  5. /// 扩展 - 可空类型
  6. /// </summary>
  7. public static partial class Extensions {
  8. /// <summary>
  9. /// 安全返回值
  10. /// </summary>
  11. /// <param name="value">可空值</param>
  12. public static int SafeValue( this int? value ) {
  13. return value.HasValue ? value.Value : ;
  14. }
  15.  
  16. /// <summary>
  17. /// 安全返回值
  18. /// </summary>
  19. /// <param name="value">可空值</param>
  20. public static Guid SafeValue( this Guid? value ) {
  21. return value.HasValue ? value.Value : Guid.Empty;
  22. }
  23.  
  24. /// <summary>
  25. /// 安全返回值,为null返回DateTime.MinValue
  26. /// </summary>
  27. /// <param name="value">可空值</param>
  28. public static DateTime SafeValue( this DateTime? value ) {
  29. return value.HasValue ? value.Value : DateTime.MinValue;
  30. }
  31.  
  32. /// <summary>
  33. /// 安全返回值
  34. /// </summary>
  35. /// <param name="value">可空值</param>
  36. public static bool SafeValue( this bool? value ) {
  37. return value.HasValue && value.Value;
  38. }
  39.  
  40. /// <summary>
  41. /// 安全返回值
  42. /// </summary>
  43. /// <param name="value">可空值</param>
  44. public static double SafeValue( this double? value ) {
  45. return value.HasValue ? value.Value : ;
  46. }
  47.  
  48. /// <summary>
  49. /// 安全返回值
  50. /// </summary>
  51. /// <param name="value">可空值</param>
  52. public static decimal SafeValue( this decimal? value ) {
  53. return value.HasValue ? value.Value : ;
  54. }
  55. }
  56. }

  在Util.Tests测试项目的Extensions目录中,添加NullableExtensionTest,代码如下。

  1. using System;
  2. using Microsoft.VisualStudio.TestTools.UnitTesting;
  3.  
  4. namespace Util.Tests.Extensions {
  5. /// <summary>
  6. /// 可空类型扩展
  7. /// </summary>
  8. [TestClass]
  9. public class NullableExtensionTest {
  10. /// <summary>
  11. /// 测试可空整型
  12. /// </summary>
  13. [TestMethod]
  14. public void TestSafeValue_Int() {
  15. int? value = null;
  16. Assert.AreEqual( , value.SafeValue() );
  17.  
  18. value = ;
  19. Assert.AreEqual( , value.SafeValue() );
  20. }
  21.  
  22. /// <summary>
  23. /// 测试可空Guid
  24. /// </summary>
  25. [TestMethod]
  26. public void TestSafeValue_Guid() {
  27. Guid? value = null;
  28. Assert.AreEqual( Guid.Empty, value.SafeValue() );
  29.  
  30. value = Guid.NewGuid();
  31. Assert.AreEqual( value.Value, value.SafeValue() );
  32. }
  33.  
  34. /// <summary>
  35. /// 测试可空DateTime
  36. /// </summary>
  37. [TestMethod]
  38. public void TestSafeValue_DateTime() {
  39. DateTime? value = null;
  40. Assert.AreEqual( DateTime.MinValue, value.SafeValue() );
  41.  
  42. value = Conv.ToDate( "2000-1-1" );
  43. Assert.AreEqual( value.Value, value.SafeValue() );
  44. }
  45.  
  46. /// <summary>
  47. /// 测试可空bool
  48. /// </summary>
  49. [TestMethod]
  50. public void TestSafeValue_Boolean() {
  51. bool? value = null;
  52. Assert.AreEqual( false, value.SafeValue() );
  53.  
  54. value = true;
  55. Assert.AreEqual( true, value.SafeValue() );
  56. }
  57.  
  58. /// <summary>
  59. /// 测试可空double
  60. /// </summary>
  61. [TestMethod]
  62. public void TestSafeValue_Double() {
  63. double? value = null;
  64. Assert.AreEqual( , value.SafeValue() );
  65.  
  66. value = 1.1;
  67. Assert.AreEqual( 1.1, value.SafeValue() );
  68. }
  69.  
  70. /// <summary>
  71. /// 测试可空decimal
  72. /// </summary>
  73. [TestMethod]
  74. public void TestSafeValue_Decimal() {
  75. decimal? value = null;
  76. Assert.AreEqual( , value.SafeValue() );
  77.  
  78. value = 1.1M;
  79. Assert.AreEqual( 1.1M, value.SafeValue() );
  80. }
  81. }
  82. }

  以后通过SafeValue方法就可以安全的获取可空值类型了。

  calvinK同学给出一个更好的方案,代码如下,在此表示感谢。

  1. namespace Util {
  2. /// <summary>
  3. /// 扩展 - 可空类型
  4. /// </summary>
  5. public static partial class Extensions {
  6. /// <summary>
  7. /// 安全返回值
  8. /// </summary>
  9. /// <param name="value">可空值</param>
  10. public static T SafeValue<T>( this T? value ) where T : struct {
  11. return value ?? default( T );
  12. }
  13. }
  14. }

  .Net应用程序框架交流QQ群: 386092459,欢迎有兴趣的朋友加入讨论。

  谢谢大家的持续关注,我的博客地址:http://www.cnblogs.com/xiadao521/

  下载地址:http://files.cnblogs.com/xiadao521/Util.2015.1.6.1.rar

Util应用程序框架公共操作类(十):可空值类型扩展的更多相关文章

  1. Util应用程序框架公共操作类(十二):Lambda表达式公共操作类(三)

    今天在开发一个简单查询时,发现我的Lambda操作类的GetValue方法无法正确获取枚举类型值,以至查询结果错误. 我增加了几个单元测试来捕获错误,代码如下. /// <summary> ...

  2. Util应用程序框架公共操作类(七):Lambda表达式公共操作类

    前一篇扩展了两个常用验证方法,本文将封装两个Lambda表达式操作,用来为下一篇的查询扩展服务. Lambda表达式是一种简洁的匿名函数语法,可以用它将方法作为委托参数传递.在Linq中,大量使用La ...

  3. Util应用程序框架公共操作类

    随笔分类 - Util应用程序框架公共操作类 Util应用程序框架公共操作类 Util应用程序框架公共操作类(五):异常公共操作类 摘要: 任何系统都需要处理错误,本文介绍的异常公共操作类,用于对业务 ...

  4. Util应用程序框架公共操作类(二):数据类型转换公共操作类(源码篇)

    上一篇介绍了数据类型转换的一些情况,可以看出,如果不进行封装,有可能导致比较混乱的代码.本文通过TDD方式把数据类型转换公共操作类开发出来,并提供源码下载. 我们在 应用程序框架实战十一:创建VS解决 ...

  5. Util应用程序框架公共操作类(九):Lambda表达式扩展

    上一篇对Lambda表达式公共操作类进行了一些增强,本篇使用扩展方法对Lambda表达式进行扩展. 修改Util项目的Extensions.Expression.cs文件,代码如下. using Sy ...

  6. Util应用程序框架公共操作类(八):Lambda表达式公共操作类(二)

    前面介绍了查询的基础扩展,下面准备给大家介绍一些有用的查询封装手法,比如对日期范围查询,数值范围查询的封装等,为了支持这些功能,需要增强公共操作类. Lambda表达式公共操作类,我在前面已经简单介绍 ...

  7. Util应用程序框架公共操作类(六):验证扩展

    前面介绍了仓储的基本操作,下面准备开始扩展查询,在扩展查询之前,首先要增加两个公共操作类,一个是经常要用到的验证方法,另一个是Lambda表达式的操作类. 很多时候,我们会判断一个对象是否为null, ...

  8. Util应用程序框架公共操作类(五):异常公共操作类

    任何系统都需要处理错误,本文介绍的异常公共操作类,用于对业务上的错误进行简单支持. 对于刚刚接触.Net的新手,碰到错误的时候,一般喜欢通过返回bool值的方式指示是否执行成功. public boo ...

  9. Util应用程序框架公共操作类(四):验证公共操作类

    为了能够验证领域实体,需要一个验证公共操作类来提供支持.由于我将使用企业库(Enterprise Library)的验证组件来完成这项任务,所以本文也将演示对第三方框架的封装要点. .Net提供了一个 ...

随机推荐

  1. script async 和script defer的区别

    浏览器对js文件的操作主要有两部分:下载和执行: js文件下载在有些浏览器中是并行的,在有些浏览器中是串行的,如:IE8.firefox3.chrome2都是串行下载的: 执行在所有浏览器中默认是阻塞 ...

  2. mysql之触发器trigger

    触发器(trigger):监视某种情况,并触发某种操作. 触发器创建语法四要素:1.监视地点(table) 2.监视事件(insert/update/delete) 3.触发时间(after/befo ...

  3. Hibernate一对多配置

    刚刚学习了Hibernate框架的基础知识,下面我来说说关于Hibernate一对多的配置 首先是大配置 连接数据库 用户名 和密码 能和小配置连接 部门小配置: 员工小配置: 部门实体类 员工实体类 ...

  4. 【三】用Markdown写blog的常用操作

    本系列有五篇:分别是 [一]Ubuntu14.04+Jekyll+Github Pages搭建静态博客:主要是安装方面 [二]jekyll 的使用 :主要是jekyll的配置 [三]Markdown+ ...

  5. (一)Linux相关内容的简介

    1.Linux内核官网:www.kernel.org 2.Linux主要发行版本: (1)redhat  服务器中常见(部分功能收费); (2)Ubuntu  图形界面较好,但是服务器中很少用: (3 ...

  6. poj1002-487-3279(字符串处理)

    一,题意: 中文题,不解释!二,思路: 1,处理输入的电话号码 2,排序num[]数组 3,输出三,步骤: 1,消除 -.Q.Z 三种字符,将一个电话号码转化为一个整数存如num[]数组 如:num[ ...

  7. C#_技巧:计算代码块运行的时间

    System.Diagnostics下类Stopwatch,给程序代码块运行计时, 利用start()和stop()方法来标记代码快. 该命名空间下还有一些其他类,可以对程序进行诊断(diagnosi ...

  8. TaintDroid剖析之File & Memiry & Socket级污点传播

    TaintDroid剖析之File & Memiry & Socket级污点传播 作者:简行.走位@阿里聚安全 1.涉及到的代码文件 TaintDroid在File, Memory以及 ...

  9. Azure 新的管理模式 —— Resource Manager

    var appInsights=window.appInsights||function(config){ function r(config){t[config]=function(){var i= ...

  10. node(async原理)

    node中的async是用来实现同步操作的,提供包括map.Series等方法,本文不做赘述. 由于项目需要在浏览器端用了async.js,因此仔细看了下它的代码.原来,一直以为node是在服务端调用 ...