可为空的引用类型

我们知道,在C#中,数据类型分为值类型和引用类型,值类型的变量不可以为空,而引用类型的变量可以为空。

但是,在使用引用类型的时候,如果不注意检查引用类型变量是否可为空,程序中就有困难出现NullReferenceException异常。

C#8.0中提供了”可为空的引用类型”语法,可以在引用类型后添加”?”修饰符声明这个类型是可为空的。

对于没有添加”?”修饰符的引用类型的变量,当编译器发现存在为这个变量赋值null的可能性的时候,编译器会给出警告信息。

在Visual Studio 2022 中,这个特性是默认启用的,可以通过删除项目*.csproj文件中的<Nullable>disable</Nullable>关闭这个特性。

如下代码所示,编写一个包含Name、PhoneNumber两个属性的Student类。

C#
  public class Student
  {
      public string Name { get; set; }

      public string PhoneNumber { get; set; }

      public Student(string name)
      {
          this.Name = name;
      }
  }

上面的代码在编译的时候,编译器会给出”在退出构造方法时,不可为null的属性PhoneNumber必须包含非null值”这样的警告信息。

Name、PhoneNumber两个属性都是string类型,因此它们都是”不可为空的string类型”,但是Student类的构造方法中只为Name属性赋值了,这样就存在PhoneNumber属性没有被赋值,从而导致其属性值为空的可能性,因此编译器给出了这样的警告信息。

如果想消除这个警告信息,可以将构造方法声明为Student(string name,string phoneNumber),并为两个属性都赋值,但是如果PhoneNumber属性确实可以为空,就可以把PhoneNumber属性声明为string?类型,也就是允许为空的string类型。

如以下代码所示:

C#
 public class Student
 {
     public string Name { get; set; }

     public string? PhoneNumber { get; set; }

     public Student(string name)
     {
         this.Name = name;
     }
 }

由于上面定义的Student类的PhoneNumber属性可能为空,因此下面的代码中的第五行执行后会出现”解引用可能出现空引用”这样的警告信息。

C#
  Student student = new(string.Empty);

  Console.WriteLine(student.Name.ToLower());

  Console.WriteLine(student.PhoneNumber.ToLower();

可以用非空检查来对PhoneNumber属性来避免这个警告

C#
            Student student = new(string.Empty);

            Console.WriteLine(student.Name.ToLower());

            if (student.PhoneNumber != null)
            {
                Console.WriteLine(student.PhoneNumber.ToLower());
            }
            else
            {
                Console.WriteLine("手机号为空");
            }

当然,如果确认被访问的变量、成员不会出现为空的情况,也可以在访问可为空的变量、成员的时候加上!来抑制编译器的警告。

当然,要尽量避免使用!印制警告。

C#
Student student = new(string.Empty);

Console.WriteLine(student.Name.ToLower());

Console.WriteLine(student.PhoneNumber!.ToLower());

对于可为空的引用类型的属性,编译器会在属性上添加NullableAttribute,因此可以在运行时通过反射判断一个引用类型属性的可空性。

很多.NET下的框架都充分利用了可为空的引用类型,从而对引用类型的属性、参数等进行更加智能化的处理。

订阅评论
提醒
0 评论
最旧
最新 最多投票
内联反馈
查看所有评论
滚动至顶部