C# - 可空类型 Nullable Types

如您所知,不能为值类型分配空值。 例如, 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.”

type? 可空类型的简写语法

您可以使用"?"运算符来简写语法,例如 int?,long? 而不是使用 Nullable。 DateTime?

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

Nullable Helper 类

一个值为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 被认为比所有的其它的值都小

可空类型的特征

  • 可空类型只能与值类型一起使用。(引用类型本身就可以为null)
  • 如果值为 null,则 Value 属性将抛出 InvalidOperationException; 否则它将返回值。
  • 如果变量包含一个值,则 HasValue 属性返回 true,如果它为 null,则返回 false。
  • 您只能将 == 和 != 运算符用于可空类型。 对于其他比较,请使用 Nullable 静态类。
  • 不允许嵌套的可为空类型。 Nullable<Nullable> i; 会给出编译时错误。
上一篇:C# 动态类型
最近更新的
...