三、将基于Nullable<T>的类型转换实现在扩展方法中

从上面的介绍我们可以得出这样的结论:如果类型T1和T2能够相互兼容,我们可以借助Convert将T1类型对象转换成T2类型,然后通过显式类型转换进一步转换成Nullable<T2>。我们可以通过这两个步骤实现针对于Nullable<T>类型的转换。为了操作方便,我将此转换逻辑写在针对IConvertible接口的扩展方法中:

   1: public static class ConvertionExtensions
   2: {
   3:     public static T? ConvertTo<T>(this IConvertible convertibleValue) where T : struct
   4:     {
   5:         if (null == convertibleValue)
   6:         {
   7:             return null;
   8:         }
   9:         return (T?)Convert.ChangeType(convertibleValue, typeof(T));
  10:     }
  11: }

借助于上面这个扩展方法ConvertTo,对于目标类型为Nullable<T>的转换就显得很简单了:

   1: int? intValue           = "123".ConvertTo<int>();
   2: double? doubleValue     = "123".ConvertTo<double>();
   3: DateTime? dateTimeValue = "1981-08-24".ConvertTo<DateTime>();

四、进一步完善扩展方法ConvertTo

上面定义的扩展方法只能完成针对目标类型为Nullable<T>的转换。现在我们来进一步完善它,让这个方法可以实现任意类型之间的转换。下面是我们新版本的ConvertTo方法的定义:

   1: public static T ConvertTo<T>(this IConvertible convertibleValue)
   2: {
   3:     if (null == convertibleValue)
   4:     {
   5:         return default(T);
   6:     }
   7:  
   8:     if (!typeof(T).IsGenericType)
   9:     {
  10:         return (T)Convert.ChangeType(convertibleValue, typeof(T));
  11:     }
  12:     else
  13:     {
  14:         Type genericTypeDefinition = typeof(T).GetGenericTypeDefinition();
  15:         if (genericTypeDefinition == typeof(Nullable<>))
  16:         {
  17:             return (T)Convert.ChangeType(convertibleValue, Nullable.GetUnderlyingType(typeof(T)));
  18:         }
  19:     }
  20:     throw new InvalidCastException(string.Format("Invalid cast from type \"{0}\" to type \"{1}\".", convertibleValue.GetType().FullName, typeof(T).FullName));

将基于Nullable<T>的类型转换实现在扩展方法中的更多相关文章

  1. 谈谈Nullable<T>的类型转换问题

    本篇文章讨论可空值类型(Nullable<T>)的转换,却确地说是如何将一种类型的值对象转换成相应的可空值.这来源于今天我们的一个成员遇到的一个小问题,我经过一些整理写了这篇文章.虽然没有 ...

  2. struts基于ognl的自动类型转换需要注意的地方

    好吧,坎坷的过程我就不说了,直接上结论: 在struts2中使用基于ognl的自动类型转换时,Action中的对象属性必须同时添加get/set方法. 例如: 客户端表单: <s:form ac ...

  3. (转)再不用担心DataRow类型转换和空值了(使用扩展方法解决高频问题)

    再不用担心DataRow类型转换和空值了(使用扩展方法解决高频问题) XML文档操作集锦(C#篇) webapi文档描述-swagger

  4. 基于 Annotation 拦截的 Spring AOP 权限验证方法

    基于 Annotation 拦截的 Spring AOP 权限验证方法 转自:http://www.ibm.com/developerworks/cn/java/j-lo-springaopfilte ...

  5. 再不用担心DataRow类型转换和空值了(使用扩展方法解决高频问题)

    在使用DataRow读取数据时,通常会遇到数据可能为Null, 但是又需要转换为如int等其它类型的数据,因此就通常会写这样的代码: if (dr[name] != DBNull.Value & ...

  6. 【FBA】SharePoint 2013自定义Providers在基于表单的身份验证(Forms-Based-Authentication)中的应用

    //http://www.cnblogs.com/OceanEyes/p/custom-provider-in-sharepoint-2013-fba-authentication.html 由于项目 ...

  7. [FBA]SharePoint 2013自定义Providers在基于表单的身份验证(Forms-Based-Authentication)中的应用

    //http://tech.ddvip.com/2014-05/1401197453210723.html 由于项目的需要,登录SharePoint Application的用户将从一个统一平台中获取 ...

  8. SharePoint 2013自定义Providers在基于表单的身份验证(Forms-Based-Authentication)中的应用

    由于项目的需要,登录SharePoint Application的用户将从一个统一平台中获取,而不是从Domain中获取,所以需要对SharePoint Application的身份验证(Claims ...

  9. AIOps探索:基于VAE模型的周期性KPI异常检测方法——VAE异常检测

    AIOps探索:基于VAE模型的周期性KPI异常检测方法 from:jinjinlin.com   作者:林锦进 前言 在智能运维领域中,由于缺少异常样本,有监督方法的使用场景受限.因此,如何利用无监 ...

随机推荐

  1. BZOJ2689 : 堡垒

    问题等价于每个三角形里至少选择两个点. 考虑拓扑,每次取出度数为$2$的点$x$,代表一个只与最多一个三角形相邻的三角形$(x,y,z)$. 如果$x$已选,那么$(x,y)$以及$(x,z)$都已经 ...

  2. python系统编程(四)

    进程池Pool 当需要创建的子进程数量不多时,可以直接利用multiprocessing中的Process动态成生多个进程,但如果是上百甚至上千个目标,手动的去创建进程的工作量巨大,此时就可以用到mu ...

  3. Cow Exhibition [POJ2184] [DP] [背包的负数处理]

    题意: 有很多羊,每只羊有一个幽默度和智商,要选出一些羊,智商加幽默度总和最大,其中智商总和和幽默度总和都不能是负数. 样例输入: 5 -5 7 8 -6 6 -3 2 1 -8 -5 样例输出: 8 ...

  4. echarts中dataZoom的使用

    ataZoom的使用方法 功能: 1.有inslide和slide两种dataZoom,也分X,Y轴 两种dataZoom的使用 dataZoom:[ { type:"slider" ...

  5. Ruby语法基础(二)

    Ruby语法基础(二) 继续ruby的学习,这次主要把目光放到运算符,条件判断,循环,方法,以及其他ruby特有的基本概念上 运算符 算术运算符:+,-,/,%,**,值的注意的是,ruby中一切皆为 ...

  6. docker 报错: Job for docker.service failed because the control process exited with error code. See "systemctl status docker.service" and "journalctl -xe" for details.

    centos 启动docker服务报错: Job for docker.service failed because the control process exited with error cod ...

  7. 一个ner的bug

    整个机器人代码之前都是好好的,今天启动的时候,就报Initialization failed! 的错误,然后想着其他模块应该没有问题.然后单独运行或者叫测试吧,测试了下 search_eng.py,发 ...

  8. 替换空字符NULL(字符编码为0的字符)

    老R3(非Unicode系统),发现读取出来的数据中有编码为0的字符,存文件后发现串行,所以需要先替换 DATA: str TYPE string. *str = zacct_12-txt+47. s ...

  9. android:Android中用文件初始化sqlite数据库(zz)

        很多时候在应用安装初始化时,需要创建本地数据库,同时为数据库添加数据,之后再从数据库中读取数据. 这里有2个思路 1.先在本地创建一个能支持android使用的sqlite数据库文件,启动时, ...

  10. ubuntu下安装配置apache2与php

    1:安装apache2 sudo apt install apache2 2:修改端口号 sudo vi /etc/apache2/ports.conf 3:修改跟目录 在 /etc/apache2/ ...