在.net2.0以前,值类型是不充许赋值为null的,这也是值类型和引用类型的一个重要区别。随着.net2.0的出现,这一局面得以改善,这种功能有点像数据库中的数据类型(int,datetime等),在数据库中列都可以设置是否可为Null。C#实现这种功能主要是依靠一个重要的结构:Nullable<T>,我们先看下它的实现:

[Serializable]
    public struct Nullable<T> where T : struct
    {
        //
        // 摘要:
        //     Initializes a new instance of the System.Nullable<T> structure to the specified
        //     value.
        //
        // 参数:
        //   value:
        //     A value type.
        public Nullable(T value);

public static explicit operator T(T? value);
        public static implicit operator T?(T value);

// 摘要:
        //     Gets a value indicating whether the current System.Nullable<T> object has
        //     a value.
        //
        // 返回结果:
        //     true if the current System.Nullable<T> object has a value; false if the current
        //     System.Nullable<T> object has no value.
        public bool HasValue { get; }
        //
        // 摘要:
        //     Gets the value of the current System.Nullable<T> value.
        //
        // 返回结果:
        //     The value of the current System.Nullable<T> object if the System.Nullable<T>.HasValue
        //     property is true. An exception is thrown if the System.Nullable<T>.HasValue
        //     property is false.
        //
        // 异常:
        //   System.InvalidOperationException:
        //     The System.Nullable<T>.HasValue property is false.
        public T Value { get; }

// 摘要:
        //     Indicates whether the current System.Nullable<T> object is equal to a specified
        //     object.
        //
        // 参数:
        //   other:
        //     An object.
        //
        // 返回结果:
        //     true if the other parameter is equal to the current System.Nullable<T> object;
        //     otherwise, false. This table describes how equality is defined for the compared
        //     values: Return Value Description true The System.Nullable<T>.HasValue property
        //     is false, and the other parameter is null. That is, two null values are equal
        //     by definition.  -or- The System.Nullable<T>.HasValue property is true, and
        //     the value returned by the System.Nullable<T>.Value property is equal to the
        //     other parameter.  false The System.Nullable<T>.HasValue property for the
        //     current System.Nullable<T> structure is true, and the other parameter is
        //     null.  -or- The System.Nullable<T>.HasValue property for the current System.Nullable<T>
        //     structure is false, and the other parameter is not null.  -or- The System.Nullable<T>.HasValue
        //     property for the current System.Nullable<T> structure is true, and the value
        //     returned by the System.Nullable<T>.Value property is not equal to the other
        //     parameter.
        public override bool Equals(object other);
        //
        // 摘要:
        //     Retrieves the hash code of the object returned by the System.Nullable<T>.Value
        //     property.
        //
        // 返回结果:
        //     The hash code of the object returned by the System.Nullable<T>.Value property
        //     if the System.Nullable<T>.HasValue property is true, or zero if the System.Nullable<T>.HasValue
        //     property is false.
        public override int GetHashCode();
        //
        // 摘要:
        //     Retrieves the value of the current System.Nullable<T> object, or the object's
        //     default value.
        //
        // 返回结果:
        //     The value of the System.Nullable<T>.Value property if the System.Nullable<T>.HasValue
        //     property is true; otherwise, the default value of the current System.Nullable<T>
        //     object. The type of the default value is the type argument of the current
        //     System.Nullable<T> object, and the value of the default value consists solely
        //     of binary zeroes.
        public T GetValueOrDefault();
        //
        // 摘要:
        //     Retrieves the value of the current System.Nullable<T> object, or the specified
        //     default value.
        //
        // 参数:
        //   defaultValue:
        //     A value to return if the System.Nullable<T>.HasValue property is false.
        //
        // 返回结果:
        //     The value of the System.Nullable<T>.Value property if the System.Nullable<T>.HasValue
        //     property is true; otherwise, the defaultValue parameter.
        public T GetValueOrDefault(T defaultValue);
        //
        // 摘要:
        //     Returns the text representation of the value of the current System.Nullable<T>
        //     object.
        //
        // 返回结果:
        //     The text representation of the value of the current System.Nullable<T> object
        //     if the System.Nullable<T>.HasValue property is true, or an empty string ("")
        //     if the System.Nullable<T>.HasValue property is false.
        public override string ToString();

Nullable<T>数据类型:Nullable<T>能够使C#中的值类型赋值为null,但同时它本身是一个值类型。这个结构的实例比较小,在存储上依然可以存储在堆栈上。

            Nullable<int> i = 1;
            Nullable<int> j = null;

生成的IL代码足以说明Nullable<T>本身是值类型:

.locals init ([0] valuetype [mscorlib]System.Nullable`1<int32> i,
[1] valuetype [mscorlib]System.Nullable`1<int32> j)

Nullable<T>的取值,既然能够充许值类型为null,那么如何读取值呢?

第一:Nullable<T>属性
            1:HasValue:获取一个值,指示当前的 Nullable<T> 对象是否有值。
            2:Value:获取当前的 Nullable<T> 值。如果hasValue等于false,则会抛出异常。

第二:Nullable<T>中包含两个特别重要的方法:
            1:T GetValueOrDefault();检索当前 Nullable<T> 对象的值,或该对象的默认值。internal T value=default(T),这个私有字段可以保证返回一个相应类型的默认值。
            2:T GetValueOrDefault(T defaultValue);检索当前 Nullable<T> 对象的值或指定的默认值。

Nullable<T>的别名:Nullable<int> 可以写成int?,这是为了方便书写等原因设计。下面的代码是等价的:

int? i=3;//Nullable<int> i=3
int?j=null;//Nullable<int> j=null

Nullable<T>对操作符的影响:

1:一元操作符,如果操作数null,则结果返回null;
           2:二元操作符,如果其中一个操作符为null,结果返回null
           3:叛等:
             1>如果两个操作数都为null,返回true。
             2>如果有一个操作数为null,返回false。
             3>如果两个操作数都不为null,则比较两个操作数的Value。
          4:比较操作符:
            1>如果其中一个操作数为null,则返回false。
            2>如果两个都不为null,则比较两个操作数的Value。

C#对Nullable<T>的应用:??操作符:如果 ?? 运算符的左操作数非 null,该运算符将返回左操作数,否则返回右操作数。它结合了判断对象是否为空的操作。下面的代码是等价的:可以看出代码简洁不少。

DateTime  k = j ?? DateTime.Now ;
DateTime kk=j==null ?DateTime .Now :(DateTime )j ;

Nullable Value Type的GetType方法,一个类型申明成Nullable<T>,我们理所当然的认为这个变量的类型会是Nullable<T>,但实际并非我们想象的那样。这里并不会返回Nullable(Int32),而是会返回System.Int32。CLR会直接返回T的类型,而不是Nullable<T>。

Int32? i=1;
i.GetType();

Nullable Value Type对接口方法的影响:我们来看下Nullable<int> 和int在调用IComparable的区别。Nullable<int>并没有实现IComparable接口,但int有实现,所以我样想调用ToCompareTo方法可以这样写(CLR)对Nullable<T>有特殊处理:

Int32? i = 1;
Int32  iResult = ((IComparable)i).CompareTo(1);

如果没有CLR对Nullable<T>的特殊支持,我们需要这样写,明显可以看出是比较麻烦的方法:

 Int32 iResult2 = ((IComparable)(Int32)i).CompareTo(1);

转载于:https://www.cnblogs.com/ASPNET2008/archive/2009/06/19/1506366.html

Nullable Value Type相关推荐

  1. java nullable,Nullable类型作为通用参数可能吗?

    回答(10) 2 years ago 将返回类型更改为Nullable,并使用非可空参数调用该方法 static void Main(string[] args) { int? i = GetValu ...

  2. GetProperty反射赋值SetValue报错:类型“System.Byte”的对象无法转换为类型“System.Nullable`1[System.Int32]”。

    在数据库读取DataTable进行实体转换的时候报错,仔细看数据库的类型是tinyint,null,而实体类中的类型是int?,这时候就会报错 原来出错的代码是这样的: private static ...

  3. 微软在C# 8中引入预览版可空引用类型

    微软已经为开发者提供了预览版的可空引用类型(Nullable Reference Type),想尝鲜的开发者可以尝试这个新特性,并提供反馈. \\ 预览版可空引用类型是Visual Studio 20 ...

  4. Spring 4 MVC+Hibernate 4+MySQL+Maven使用注解集成实例

    Spring 4 MVC+Hibernate 4+MySQL+Maven使用注解集成实例 转自:通过注解的方式集成Spring 4 MVC+Hibernate 4+MySQL+Maven,开发项目样例 ...

  5. 【广州.NET社区线下活动】云定未来 - Azure Meetup

    第2届 广州.NET线下沙龙 Azure Meetup 4月13日,第2届广州.NET线下沙龙在广州银行大厦7楼中创学院路演大厅成功举办.来自微软MVP.网易的技术专家们带来了干货满满的知识分享,即使 ...

  6. springboot-springmvc响应json与xml原理-详解数据响应与内容协商(长文预警,收藏慢啃)

    目录 一.springmvc响应json 1. web场景自动引入了json场景 2.使用方式 二.springmvc响应json数据原理 1.springmvc请求处理逻辑 2.返回值的处理 3.返 ...

  7. Android内部存储与外部存储解析

    Android开发的过程中.经常会涉及到存储,之前一直没有一个整体的概念,这篇文章就是进行一个知识点的梳理. Android的存储有:内部存储.外部存储. 想要了解这两个概念,我们先将开发软件中的DD ...

  8. 体验.NET5 RC1极致性能,你也要“卧槽”!

    " 9月14日,.NET5发布了(Release Candidate)RC1版本,是11月正式版本之前两个RC版本中第一个,包含语言新版本C#9和F#5,需要用Visual Studio 2 ...

  9. 【翻译】.NET 5 RC1发布

    9月14日,.NET5发布了(Release Candidate)RC1版本,RC的意思是指我们可以进行使用,并且RC版本得到了支持,该版本是接近.NET5的版本,也是11月正式版本之前两个RC版本中 ...

最新文章

  1. Hadoop + HBase (自带zookeeper 也可单独加) 集群部署
  2. 不用GPU,稀疏化也能加速你的YOLOv3深度学习模型
  3. ceph集群删除mds服务
  4. 智能云改-docker云迁移实战
  5. deep linux 看视频卡,在Deepin 20等Linux系统下用Chrome看虎牙直播经常卡的处理
  6. Codeforces Round #296 (Div. 1) E. Triangles 3000
  7. Julia也能做爬虫?可以,但没必要
  8. OOP编程思想(封装 继承 多态)
  9. Android之利用volley搭建简洁网络框架
  10. 山西等保测评机构项目测评收费价格标准参考
  11. Python 转义字符(含用法)
  12. Pdf怎么设置页码,从正文开始
  13. win7用友u8安装教程_如何在win7系统中安装用友u8(图文)
  14. SDCC编译器简明使用教程
  15. Win10优化:系统文件Hiberfil.sys介绍
  16. php老虎杠子鸡虫条件,老虎、杠子、鸡——在游戏中学习
  17. Memcached replace 命令
  18. Transition of CSS3
  19. 腾讯、阿里和百度的12大隐藏良心级实用功能(24K纯干货!)
  20. c++ 编译 curl 报错 数组‘__curl_rule_01__’的大小为负 解决方法

热门文章

  1. 2017第48周四乔布斯语录
  2. 【无标题】高压输电线路在线监测的重要性
  3. arduino与电子罗盘模块
  4. Paste mac键盘快捷方式
  5. 无线耳机什么牌子的好?质量好性价比高 ?八款蓝牙耳机分享
  6. PostFix+Dovecot 部署邮件系统
  7. 在ArcGIS中发布GoogleEarth瓦片为网络地图服务(wms)
  8. 关于趋势系数和气候倾向率
  9. 电子静压式液位计的几种安装要求
  10. JavaScript代码规范及分号问题