众所周知,不能为值类型分配空值。例如,int i = null 将抛出编译时错误。
c# 2.0引入了可空类型,允许你将null赋值给值类型变量。您可以使用 Nullable<t> 来声明可空类型,其中 T 是一个类型。
可空类型定义
示例:可空类型
Nullable<int> i = null;
可空类型可以表示其基础值类型的正确值范围,还外加一个额外的空值。例如,Nullable < int > 可以分配从 -2147483648 到 2147483647 的任何值,或者一个 null 值。
Nullable 类型是 System.Nullable < t > struct 的实例。
示例:可空结构
[Serializable]
public struct Nullable<T> where T : struct
{
public bool HasValue { get; }
public T Value { get; }
// 其他实现
}
Int 类型的 nullable 与普通 int 类型相同,加上一个标志,表示 int 是否有一个值(是否为 null)。。其余所有都是编译器魔术,它将“ null”视为有效值。
示例:HasValue
static void Main(string[] args)
{
Nullable<int> i = null;
if (i.HasValue)
Console.WriteLine(i.Value); // 或 Console.WriteLine(i)
else
Console.WriteLine("Null");
}
输出:
Null
如果对象已分配值,则在返回 true;如果未分配任何值或已分配 null 值,则返回 false。
如果 NullableType.value 类型为 null 或未分配任何值,则使用 NullableType.value 访问该值将引发运行时异常。例如,如果 i 为 null,值将抛出一个异常:
无效使用可空类型
如果不为null,则 使用 GetValueOrDefault() 方法获取实际值;如果为null,则使用默认值。例如:
示例: GetValueOrDefault() 方法
static void Main(string[] args)
{
Nullable<int> i = null;
Console.WriteLine(i.GetValueOrDefault());
}
可空类型的简写语法
您可以使用“?” 运算符来简化语法,例如int ?, long?而不是使用Nullable <T>。
示例:Nullable类型的简写语法
int? i = null;
double? D = null;
Null 合并运算符( ?? )
使用 '??' 运算符,将可为空的类型分配给不可为空的类型。
示例:?? 可空类型的运算符
int? i = null;
int j = i ?? 0;
Console.WriteLine(j);
输出:
0
在上面的示例中,i是可为null的int,如果将其分配给不可为null的int j,则如果i为null,它将抛出运行时异常。因此,为了降低出现异常的风险,我们使用了“ ??” 运算符,如果i为null,则将0赋给j。
示例:Null 合并运算符( ?? )
using System;
namespace CalculatorApplication
{
class NullablesAtShow
{
static void Main(string[] args)
{
double? num1 = null;
double? num2 = 3.14157;
double num3;
num3 = num1 ?? 5.34; // num1 如果为空值则返回 5.34
Console.WriteLine("num3 的值: {0}", num3);
num3 = num2 ?? 5.34;
Console.WriteLine("num3 的值: {0}", num3);
Console.ReadLine();
}
}
}
输出结果:
num3 的值: 5.34
num3 的值: 3.14157
赋值规则
可空类型的赋值规则与值类型的赋值规则相同。如果在函数中将可空类型声明为局部变量,则必须在使用它之前为其赋值。如果它是任何类的字段,那么默认情况下它将有一个空值。
例如,声明并使用以下int类型的nullable而不分配任何值。编译器将给出“使用未分配的局部变量'i'”错误:
未分配的可为空的类型错误
在下面的示例中,int类型的nullable是该类的字段,因此不会产生任何错误。
示例:可空类型作为类字段
class MyClass
{
public Nullable<int> i;
}
class Program
{
static void Main(string[] args)
{
MyClass mycls = new MyClass();
if(mycls.i == null)
Console.WriteLine("Null");
}
}
输出:
Null
Nullable 类比较方法
Null被认为小于任何值。所以比较运算符不能用于null。看以下示例,其中i既不小于j,也不大于j,也不等于j:
示例:可空类型比较
static void Main(string[] args)
{
int? i = null;
int j = 10;
if (i < j)
Console.WriteLine("i < j");
else if( i > 10)
Console.WriteLine("i > j");
else if( i == 10)
Console.WriteLine("i == j");
else
Console.WriteLine("无法比较");
}
输出:
无法比较
Nullable静态类是Nullable类型的辅助类。它提供了比较可空类型的比较方法。它还具有GetUnderlyingType方法,该方法返回可为null的类型的基础类型参数。
示例:Nullable 类 Compare方法
static void Main(string[] args)
{
int? i = null;
int j = 10;
if (Nullable.Compare<int>(i, j) < 0)
Console.WriteLine("i < j");
else if (Nullable.Compare<int>(i, j) > 0)
Console.WriteLine("i > j");
else
Console.WriteLine("i = j");
}
输出:
i < j
可空类型的特性
可空类型只能与值类型一起使用。
如果 Value 为 null,则 Value 属性将抛出 InvalidOperationException; 否则将返回值。
如果变量包含值,则HasValue属性返回true;如果为null,则返回false。
只能将 == 和!= 运算符与可为空的类型一起使用。对于其他比较,请使用Nullable静态类。
不允许使用嵌套的可空类型。Nullable <Nullable <int >> i; 将给出编译时错误。
要记住的要点
Nullable <T>类型允许将null分配给值类型。
?运算符是Nullable类型的简写语法。
使用value属性获取可空类型的值。
使用HasValue属性检查是否将值分配给可空类型。
静态 Nullable 类是一个帮助器类,用于比较可空类型。