[CLR via C#]可空值类型

一、它为什么而存在

设计一个数据库时,可将一个列的数据类型定义成一个32位整数,并映射到FCL的Int32数据类型。但是,数据库中的一个列可能允许值为空,也就是说,该列在某一行上允许没有任何值。用.NET Framework处理数据库数据时可能变得相当困难,因为在CLR中,没有办法将一个Int32值表示成null。

二、它到底是什么

为了解决这个问题,Microsoft在CLR中引入了可空值类型的概念。为了理解它们是如何工作的,先来看一下System.Nullable<T>结构,注意它是一个值类型。

 1     [Serializable]
 2     public struct Nullable<T> where T : struct
 3     {
 4         private bool hasValue;
 5
 6         internal T value;
 7
 8         public bool HasValue
 9         {
10             get
11             {
12                 return this.hasValue;
13             }
14         }
15         public T Value
16         {
17             get
18             {
19                 if (!this.HasValue)
20                 {
21                     throw new InvalidOperationException("Nullable object must have a value.");
22                 }
23                 return this.value;
24             }
25         }
26
27         public Nullable(T value)
28         {
29             this.value = value;
30             this.hasValue = true;
31         }
32
33         public T GetValueOrDefault()
34         {
35             return this.value;
36         }
37         public T GetValueOrDefault(T defaultValue)
38         {
39             if (!this.HasValue)
40             {
41                 return defaultValue;
42             }
43             return this.value;
44         }
45         public override bool Equals(object other)
46         {
47             if (!this.HasValue)
48             {
49                 return other == null;
50             }
51             return other != null && this.value.Equals(other);
52         }
53         public override int GetHashCode()
54         {
55             if (!this.HasValue)
56             {
57                 return 0;
58             }
59             return this.value.GetHashCode();
60         }
61         public override string ToString()
62         {
63             if (!this.HasValue)
64             {
65                 return "";
66             }
67             return this.value.ToString();
68         }
69         public static implicit operator T?(T value)
70         {
71             return new T?(value);
72         }
73         public static explicit operator T(T? value)
74         {
75             return value.Value;
76         }
77     }

1.当使用Nullable<Int32> x = 5时,实际上调用了Nullable的有参构造函数来初始化值类型。

2.当使用Nullable<Int32> x = null时,实际上调用了Nullable的无参构造函数来初始化值类型。

三、C#对可空值类型的支持

C#允许用问号表示法来声明并初始化可空值类型,如Int32? x = 5,相当于Nullable<Int32> x = new Nullable<Int32>(5);

1.C#允许开发人员在可空实例上执行转换和转型

Int32? a = 5;

//通过查看IL可知,实际上是获取了Value属性的值再赋值给b。所以如果a等于Null时,下面一行代码会抛出异常。

Int32 b = (Int32)a;

//通过查看IL可知,实际上是调用了GetValueOrDefault方法获取值,然后再调用new Nullable<Double>构造函数初始化变量。

Double? c = a;

四、C#的空接合操作符

"??",获取两个操作数,假如左边的操作数不为空,就返回这个操作数的值,否则返回右边操作数的值。

五、CLR对可空值类型的特殊支持

1.可空值类型的装箱

当CLR对一个可空值类型进行装箱时,会检查它是否为空,如果为空,则CLR不进行任何装箱,并返回空值。如果可空实例不为空,CLR从可空实例中取出值,并对其进行装箱。

时间: 2025-01-18 12:46:31

[CLR via C#]可空值类型的相关文章

【C#进阶系列】18 可空值类型

可空值类型,正如字面意义上的,是可以为NULL的值类型. 这个东西存在的意义可以解决比如数据库的的Int可以为NUll的情况,使得处理数据库数据更简单. 实际上可空值类型就是Nullable<T>这个泛型值类型,而C#有一种更简单的语法糖是int?这种用法: Nullable<Int32> 数据库类型 = null; float? 可以为空的浮点类型 = null; DateTime? 更多的值类型 = null; 可空值类型的更多玩法 在大多数时候用C#去操作可空值类型,完全可以

可空值类型(类型后面加问号)

很多时候经常遇到类型后面加问号?如int? i=null,不知道标示什么,其实这是2.0的新语法:可控制类型. 由于一个值类型变量永远不可能为null,而数据库中的一个列是允许值为空的,为了与数据库中的列相对应,CLR引入了可空值类型. C#中是以问号表示法声明并初始化可空值类型的,如下代码所示: int? x=5; int? y=null; C#允许对可空值类型进行数据转换和转型,示例代码如下: int? x=5; int z =(int)x; 可以对可空值类型进行装箱.其规则是:若可空值类型

.NET 可空值类型

Microsoft在CLR中引入了可空值类型(nullable value type)的概念. FCL中定义System.Nullable<T>类如下: [Serializable,StructLayout(LayoutKind.Sequential)] public struct Nullable<T> where T: struct { private Boolean hasValue=false; internal T value=default(T); ………………(略)

可空值类型与值类型这间的转换

int s = 5; int? s_null; long t; long? t_null; t = s; //隐式转换 S -> T s = (int)t; //显示转换 T -> S s_null = s; //隐式转换 S -> S? s = (int)s_null; //显示转换 S? -> T t_null = s_null; //隐式转换 S? -> T? s_null = (int?)t_null; //显示转换 T? -> S? t_null = s; /

匹夫细说C#:可以为null的值类型,详解可空值类型

首先祝大家中秋佳节快乐~ 0x00 前言 众所周知的一点是C#语言是一种强调类型的语言,而C#作为Unity3D中的游戏脚本主流语言,在我们的开发工作中能够驾驭好它的这个特点便十分重要.事实上,怎么强调C#的这个特点都不为过,因为它牵涉到编程的很多方面.一个很好的例子便是我们本文要介绍的内容——可空型,它是因何出现的,而它的出现又有什么意义呢?以及如何在Unity3D游戏的开发中使用它呢?那么就请各位读者朋友带着这些疑问,通过下面的文字来寻找这些问题的答案吧. 0x01 如果没有值? 一个了解一

C# 可空值类型

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace 可空值类型 { class Program { static void Main(string[] args) { int? a = null; int? b = 5; Console.WriteLine(a);//空 Console.WriteL

第20课-数据库开发及ado.net 可空值类型,资料管理器,多条件查询,Case

第20课-数据库开发及ado.net 可空值类型,资料管理器,多条件查询,Case SqlHelper using System; using System.Collections.Generic; using System.Configuration; using System.Data; using System.Data.SqlClient; using System.Text; namespace _02省市联动 { public static  class SqlHelper { //

Util应用程序框架公共操作类(十):可空值类型扩展

当你使用可空的值类型时,你会发现取值很不方便,比如Guid? obj,你要从obj中获取值,可以使用Value属性obj. Value,但obj可能为null,这时候就会抛出一个异常. 可空值类型提供了一个HasValue属性,它可以识别出obj是不是一个null值,每当你获取可空值都需要加上这个判断if(value.HasValue){ var value = obj.Value;}. 下面我们通过几个扩展方法,把判断封装起来. 在Util项目中添加Extensions.Nullable.cs

可空值类型

C#中的可空值类型 C#不允许把NULL值赋给一个值类型,以下语法是错误的 int i a =null; 但是,利用 C# 定义的一个修饰符,可将一个变量声明为一个可空(nullable)值类型.可空值类型在行为上与普通值类型相似,但可以将一个 null 值赋给它.如下所示: int? a = null; // 合法 当把一个变量定义为可空值类型时,该变量依然可以被赋值为 0,代码如下所示: using System.Collections.Generic; using System.Linq;