如您所知,不能为值类型分配空值。 例如, int i = null 会给你一个编译时错误。
C# 2.0 引入了可空类型,允许您将 null 分配给值类型变量。 您可以使用 Nullable<t>
声明可为空的类型,其中 T 是一种类型。
Nullable<int> i = null;
可空类型可以表示其基础值类型的正确值范围,外加一个额外的Null。 例如,可以为 Nullable<int>
分配从 -2147483648 到 2147483647 的任何值,或null。
Nullable 类型是 System.Nullable
[Serializable]
public struct Nullable<T> where T : struct
{
public bool HasValue { get; }
public T Value { get; }
// other implementation
}
int 类型的可空对象与普通 int 相同,只是外加了一个标志,表示 int 是否有值(或为 null)。 剩下的就是将“null”视为有效值的编译器魔法。
static void Main(string[] args)
{
Nullable<int> i = null;
if (i.HasValue)
Console.WriteLine(i.Value); // or Console.WriteLine(i)
else
Console.WriteLine("Null");
}
// 输出了null
如果对象已被赋值,则 HasValue 返回 true; 如果它没有被赋值或被赋值为null,它将返回 false。
如果可空类型为 null 或未分配任何值,则使用 xx.value 访问该值将引发运行时异常。 例如,如果 i 为空, i.Value 将抛出异常:
Nullable<int> i = null;
Console.WriteLine(i.Value); //System.InvalidOperationException:“Nullable object must have a value.”
您可以使用"?"运算符来简写语法,例如 int?,long? 而不是使用 Nullable
int? i = null;
double? D = null;
DateTime? date = null;
使用'??' 运算符将可空类型分配给不可空类型。
int? i = null;
int j = i ?? 0; //如果为null的话就把0赋给j,不为null的话则把 i.value赋给j
Console.WriteLine(j);//0
在上面的例子中,i 是一个可为空的 int,如果你将它分配给不可空的 int j,那么如果 i 为空,它将抛出一个运行时异常。 因此,为了降低异常风险,我们使用了"??" 运算符来指定如果 i 为空,则将 0 分配给 j。
可空类型与值类型具有相同的赋值规则。 如果在函数中将可空类型声明为局部变量,则必须在使用之前为其分配一个值。 如果它是任何类的字段,则默认情况下它将具有空值。
例如,以下 int 类型的 nullable 被声明和使用,而没有分配任何值。 编译器会给出 使用了未赋值的局部变量“abc” 错误:
static void Main(string[] args)
{
int? abc;
Console.WriteLine(abc); //会抛出异常。主要是防止程序员粗心
}
下面的i没有赋值不会抛出异常
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
一个值为null的可空类型是没有办法比较的。如下示例
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("无法比较");
}
//输出 无法比较
我们可以用
static void Main(string[] args)
{
int? i = null;
int j = int.MinValue;
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
因为null 被认为比所有的其它的值都小