C# - 可为空的类型(Nullable Types)

本文关键字:Nullable Types 类型 | 更新日期: 2023-09-12 17:38:28

如您所知,不能为值类型分配空值。例如,int i = null 会给你一个编译时错误。

C# 2.0 引入了可为 null 的类型,允许您将 null 分配给值类型变量。可以使用 T 为类型的Nullable<t>声明可为 null 的类型。

Example: Nullable type

Nullable<int> i = null;

可为 null 的类型可以表示其基础值类型的正确值范围,以及附加的 null 值。例如,Nullable可以分配从 -2147483648 到 2147483647 的任何值,也可以分配 null 值。

可为空的类型是System.Nullable<T>结构的实例。将其视为类似于以下结构的内容。

Example: Nullable struct

[Serializable]
public struct Nullable<T> where T : struct
{        
    public bool HasValue { get; }
      
    public T Value { get; }
        
    // other implementation
}

int

类型的可为空值与普通 int 加上一个指示 int 是否有值(是否为 null)的标志相同。其余的都是编译器的魔术,它将"null"视为有效值。

Example: HasValue

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 或未分配任何值,则使用 NullableType.value 访问该值将引发运行时异常。例如,如果 i 为 null,i.Value 将引发异常:

无效使用可为空的类型

使用 GetValueOrDefault() 方法获取实际值(如果它不为 null)和默认值(如果它是 null)。例如:

Example: GetValueOrDefault()

static void Main(string[] args)
{
    Nullable<int> i = null;
    Console.WriteLine(i.GetValueOrDefault()); 
}

可为空类型的速记语法

您可以使用"?"运算符来速记语法,例如int?,long?,而不是使用Nullable<T>。

Example: Shorthand syntax for Nullable types

int? i = null;
double? D = null;

??算子

使用"??"运算符将可为空的类型分配给不可为空的类型。

Example: ?? operator with Nullable Type

int? i = null;
            
int j = i ?? 0;
Console.WriteLine(j);

输出:

0

在上面的例子中,i 是一个可为空的 int,如果将其分配给不可为空的 int j,那么如果 i 为 null,它将抛出运行时异常。因此,为了降低异常的风险,我们使用"??"运算符来指定如果 i 为 null,则将 0 分配给 j。

分配规则

可为 null 的类型与值类型具有相同的分配规则。如果在函数中将可为 null 的类型声明为局部变量,则必须在使用之前为其赋值。如果它是任何类的字段,则默认情况下它将具有空值。

例如,声明并使用以下 int 类型的 nullable 而不分配任何值。编译器将给出"使用未赋值的局部变量'i'"错误:

未赋值的可为空的类型错误

在下面的示例中,int 类型的 null 是类的字段,因此它不会给出任何错误。

Example: Nullable type as Class Field

class MyClass
{
    public Nullable<int> i;
}
class Program
{
    static void Main(string[] args)
    {
        MyClass mycls = new MyClass();
        if(mycls.i == null)
            Console.WriteLine("Null");
    }
}

输出:

0

可为空的帮助程序类

空值被视为小于任何值。因此,比较运算符不适用于 null。考虑以下示例,其中 i 既不小于 j,也不大于 j,也不等于 j:

Example: Nullable Type Comparison

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("Could not compare");
}

输出:

Could not compare

可为空的静态类是可为空类型的帮助程序类。它提供了一种比较方法来比较可为 null 的类型。它还有一个 GetUnderlyingType 方法,该方法返回可为空类型的基础类型参数。

Example: Helper Class

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

可为空类型的特征

  1. 可为 null 的类型只能与值类型一起使用。
  2. 如果值为 null,则 Value 属性将引发 InvalidOperationException;否则它将返回该值。
  3. 如果变量包含值,则 HasValue 属性返回 true;如果变量为 null,则返回 false。
  4. 只能将 == 和 != 运算符与可为 null 的类型一起使用。对于其他比较,请使用可为空的静态类。
  5. 不允许嵌套的可为空类型。Nullable> i;将给出编译时错误。

注意:

  1. 可为空<T>类型允许将空值分配给值类型。
  2. 运算符是可为 Null 类型的简写语法。
  3. 使用 value 属性获取可为 null 类型的值。
  4. 使用 HasValue 属性检查值是否分配给可为 null 的类型
  5. 静态可为空类
  6. 是用于比较可为空类型的帮助程序类。