可空类型
为啥要引入可空类型?
在数据库中,字段是可以为null值的,那么在C#中为了方便的操作数据库的值,微软引入了可空类型。
声明可空类型
我们可以使用两种方法声明一个可空类型:
1 Nullable<int> i = null; 2 int? i = null;
第二行是第一行的简写方法,其中“?”是微软为可空类型提供的一个语法糖。
我们看看可空类型的实现:
1 // Type: System.Nullable`1 2 // Assembly: mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 3 // MVID: 255ABCDF-D9D6-4E3D-BAD4-F74D4CE3D7A8 4 // Assembly location: C:\Windows\Microsoft.NET\Framework\v4.0.30319\mscorlib.dll 5 6 using System.Runtime; 7 8 namespace System 9 { 10 /// <summary> 11 /// 表示基础类型为值类型的对象,值类型与引用类型一样也可以分配 null。 12 /// </summary> 13 /// <typeparam name="T"><see cref="T:System.Nullable`1"/> 泛型类型的基础值类型。</typeparam><filterpriority>1</filterpriority> 14 [Serializable] 15 public struct Nullable<T> where T : struct 16 { 17 /// <summary> 18 /// 将 <see cref="T:System.Nullable`1"/> 结构的新实例初始化为指定值。 19 /// </summary> 20 /// <param name="value">一个值类型。</param> 21 [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")] 22 public Nullable(T value); 23 /// <summary> 24 /// 创建一个新的 <see cref="T:System.Nullable`1"/> 对象,并将其初始化为指定的值。 25 /// </summary> 26 /// 27 /// <returns> 28 /// 一个 <see cref="T:System.Nullable`1"/> 对象,其 <see cref="P:System.Nullable`1.Value"/> 属性使用 <paramref name="value"/> 参数进行初始化。 29 /// </returns> 30 /// <param name="value">一个值类型。</param> 31 public static implicit operator T?(T value); 32 /// <summary> 33 /// 返回指定的 <see cref="T:System.Nullable`1"/> 的值。 34 /// </summary> 35 /// 36 /// <returns> 37 /// <paramref name="value"/> 参数的 <see cref="P:System.Nullable`1.Value"/> 属性的值。 38 /// </returns> 39 /// <param name="value">一个 <see cref="T:System.Nullable`1"/> 值。</param> 40 public static explicit operator T(T? value); 41 /// <summary> 42 /// 检索当前 <see cref="T:System.Nullable`1"/> 对象的值,或该对象的默认值。 43 /// </summary> 44 /// 45 /// <returns> 46 /// 如果 <see cref="P:System.Nullable`1.HasValue"/> 属性为 true,则为 <see cref="P:System.Nullable`1.Value"/> 属性的值;否则为当前 <see cref="T:System.Nullable`1"/> 对象的默认值。 默认值的类型为当前 <see cref="T:System.Nullable`1"/> 对象的类型参数,而默认值的值中只包含二进制零。 47 /// </returns> 48 [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")] 49 public T GetValueOrDefault(); 50 /// <summary> 51 /// 检索当前 <see cref="T:System.Nullable`1"/> 对象的值或指定的默认值。 52 /// </summary> 53 /// 54 /// <returns> 55 /// 如果 <see cref="P:System.Nullable`1.HasValue"/> 属性为 true,则为 <see cref="P:System.Nullable`1.Value"/> 属性的值;否则为 <paramref name="defaultValue"/> 参数。 56 /// </returns> 57 /// <param name="defaultValue">如果 <see cref="P:System.Nullable`1.HasValue"/> 属性为 false,则为一个返回值。</param> 58 public T GetValueOrDefault(T defaultValue); 59 /// <summary> 60 /// 指示当前 <see cref="T:System.Nullable`1"/> 对象是否等于指定的对象。 61 /// </summary> 62 /// 63 /// <returns> 64 /// 如果 <paramref name="other"/> 等于当前的 <see cref="T:System.Nullable`1"/> 对象,则为 true;否则为 false。 此表描述如何定义所比较值的相等性: 返回值 说明 true <see cref="P:System.Nullable`1.HasValue"/> 属性为 false,并且 <paramref name="other"/> 参数为 null。 即,根据定义,两个 null 值相等。 - 或 - <see cref="P:System.Nullable`1.HasValue"/> 属性为 true,并且 <see cref="P:System.Nullable`1.Value"/> 属性返回的值等于 <paramref name="other"/> 参数。 false 当前 <see cref="T:System.Nullable`1"/> 结构的 <see cref="P:System.Nullable`1.HasValue"/> 属性为 true,并且 <paramref name="other"/> 参数为 null。 - 或 - 当前 <see cref="T:System.Nullable`1"/> 结构的 <see cref="P:System.Nullable`1.HasValue"/> 属性为 false,并且 <paramref name="other"/> 参数不为 null。 - 或 - 当前 <see cref="T:System.Nullable`1"/> 结构的 <see cref="P:System.Nullable`1.HasValue"/> 属性为 true,并且 <see cref="P:System.Nullable`1.Value"/> 属性返回的值不等于 <paramref name="other"/> 参数。 65 /// </returns> 66 /// <param name="other">一个对象。</param><filterpriority>1</filterpriority> 67 public override bool Equals(object other); 68 /// <summary> 69 /// 检索由 <see cref="P:System.Nullable`1.Value"/> 属性返回的对象的哈希代码。 70 /// </summary> 71 /// 72 /// <returns> 73 /// 如果 <see cref="P:System.Nullable`1.HasValue"/> 属性为 true,则为 <see cref="P:System.Nullable`1.Value"/> 属性返回的对象的哈希代码;如果 <see cref="P:System.Nullable`1.HasValue"/> 属性为 false,则为零。 74 /// </returns> 75 /// <filterpriority>1</filterpriority> 76 public override int GetHashCode(); 77 /// <summary> 78 /// 返回当前 <see cref="T:System.Nullable`1"/> 对象的值的文本表示形式。 79 /// </summary> 80 /// 81 /// <returns> 82 /// 如果 <see cref="P:System.Nullable`1.HasValue"/> 属性为 true,则是当前 <see cref="T:System.Nullable`1"/> 对象的值的文本表示形式;如果 <see cref="P:System.Nullable`1.HasValue"/> 属性为 false,则是一个空字符串 ("")。 83 /// </returns> 84 /// <filterpriority>1</filterpriority> 85 public override string ToString(); 86 /// <summary> 87 /// 获取一个值,指示当前的 <see cref="T:System.Nullable`1"/> 对象是否有值。 88 /// </summary> 89 /// 90 /// <returns> 91 /// 如果当前的 <see cref="T:System.Nullable`1"/> 对象具有值,则为 true;如果当前的 <see cref="T:System.Nullable`1"/> 对象没有值,则为 false。 92 /// </returns> 93 public bool HasValue { [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] get; } 94 /// <summary> 95 /// 获取当前的 <see cref="T:System.Nullable`1"/> 值。 96 /// </summary> 97 /// 98 /// <returns> 99 /// 如果 <see cref="P:System.Nullable`1.HasValue"/> 属性为 true,则为当前 <see cref="T:System.Nullable`1"/> 对象的值。 如果 <see cref="P:System.Nullable`1.HasValue"/> 属性为 false,则将引发异常。 100 /// </returns> 101 /// <exception cref="T:System.InvalidOperationException"><see cref="P:System.Nullable`1.HasValue"/> 属性为 false。</exception> 102 public T Value { [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")] get; } 103 } 104 }
我们注意一下其类的声明:
public struct Nullable<T> where T : struct
首先,可空类型是值类型而不是引用类型。
where表明了其接受的类型仅仅是值类型,当然,引用类型天生就支持为null。
使用可空类型
我们来看一个使用可空的例子:
1 using System; 2 3 namespace Study 4 { 5 class Program 6 { 7 static void Main(string[] args) 8 { 9 int? i = null; 10 11 // GetValueOrDefault() 如果为空则返回默认值 12 Console.WriteLine("是否有值:" + i.HasValue + ", 值:" + i.GetValueOrDefault()); 13 14 //赋值 15 if (!i.HasValue) 16 { 17 i = 100; 18 } 19 20 Console.WriteLine("是否有值:" + i.HasValue + ", 值:" + i.Value); 21 22 //int num = i * 2; 23 //上面的写法会报错 24 int num = i.Value * 2; 25 Console.WriteLine("num:" + num); 26 27 if (i == 100) 28 { 29 Console.WriteLine("等于100"); 30 } 31 32 Console.Read(); 33 } 34 } 35 }
输出如下:
1 是否有值:False, 值:0 2 是否有值:True, 值:100 3 num:200 4 等于100
空合并操作符
由于可空类型可以为空,所以,如果我们需要获取一个可空类型的值时,如果为null返回0,否则返回其自己的值,写法如下:
int i = nullable.HasValue ? nullable.Value : 0;
我们还可以直接使用GetValueOrDefault();方法来获取,如果是为null需要一个指定的数,如100的写法如下:
1 int i = nullable.HasValue ? nullable.Value : 100; 2 int i = nullable.GetValueOrDefault(100);
上面两种写法的效果一致。
下面我们来看看空合并操作符“??”的效果:判断左方的数,如果不为空则返回左方的数,否则返回右方的数。
比如上面的效果用空合并操作符来写如下:
int i = nullable ?? 100;
我们可以把空操作符看做一种方便的简写形式。
匿名方法
迭代器
IEnumerable、IEnumerator与yield的学习
yield学习续:yield return迭代块在Unity3D中的应用——协程
时间: 2024-10-01 03:54:41