C# - 可空类型
C# - 处理 Null
Section titled “C# - 处理 Null”在编程中,null 表示值的缺失。正确处理 null 对于编写健壮且无 bug 的应用程序至关重要。C# 提供了一套强大的功能来管理 null,主要通过可空值类型(nullable value types)和可空引用类型(nullable reference types)实现。
可空值类型 (T?)
Section titled “可空值类型 (T?)”默认情况下,像 int、double、bool 和 DateTime 这样的值类型不能为 null。它们必须始终持有一个值。然而,有时你需要表示一种“未赋值”或“未知”的状态,例如数据库中非必需的字段。
要允许值类型保存 null,你可以通过在类型名称后添加 ? 来将其声明为可空值类型。
// 普通的 int 不能为 null// int age = null; // 编译时错误
// 可空 int 可以为 nullint? age = null;
bool? isOptedIn = true;
double? temperature = 21.5;temperature = null; // 这是有效的可空类型有两个重要的属性:
HasValue:一个布尔值,如果变量包含一个值,则为true;如果为null,则为false。Value:返回底层的值。如果你在HasValue为false时尝试访问它,会抛出InvalidOperationException异常。
int? middleNameLength = null;
if (middleNameLength.HasValue){ Console.WriteLine($"Length is: {middleNameLength.Value}");}else{ Console.WriteLine("No middle name length provided.");}可空引用类型 (NRTs)
Section titled “可空引用类型 (NRTs)”C# 8 中引入的可空引用类型(Nullable Reference Types, NRTs)是防止 NullReferenceException(最常见的运行时错误之一)的游戏规则改变者。此功能帮助你表达变量(如 string 或自定义类对象)是否允许为 null 的意图。
要启用 NRTs,请在你的 .csproj 项目文件中添加以下行:
<PropertyGroup> <Nullable>enable</Nullable></PropertyGroup>启用 NRTs 后:
string name:这是一个不可为空的引用类型。如果你不初始化它或尝试将null赋值给它,编译器会发出警告。string? nickname:这是一个可空的引用类型。它明确允许为null。
启用 NRTs 的示例
Section titled “启用 NRTs 的示例”#nullable enable // 你也可以为单个文件启用此功能
string requiredField = "Some value";// requiredField = null; // 生成编译时警告!
string? optionalField = null; // 这是允许的
// 编译器会警告你 optionalField 在这里可能为 null!// Console.WriteLine(optionalField.Length);
// 在使用之前你必须检查是否为 nullif (optionalField != null){ Console.WriteLine(optionalField.Length); // 这里没有警告}与 Null 相关的运算符
Section titled “与 Null 相关的运算符”C# 提供了几个方便的运算符来处理可空类型。
空合并运算符 (??)
Section titled “空合并运算符 (??)”?? 运算符为可空类型在为 null 时提供一个默认值。它读作“如果左侧不为 null,则使用它;否则,使用右侧的值。”
string? userName = null;
// 如果 userName 为 null,则使用 "Guest"。否则,使用 userName 的值。string displayName = userName ?? "Guest";
Console.WriteLine(displayName); // 输出: Guest空合并赋值运算符 (??=)
Section titled “空合并赋值运算符 (??=)”??= 运算符(C# 8+)仅当左侧变量为 null 时,才将右侧值赋值给左侧变量。
List<int>? numbers = null;
// 如果 numbers 为 null,则创建一个新列表并将其赋值给 numbers。numbers ??= new List<int>();
numbers.Add(42);Console.WriteLine(numbers.Count); // 输出: 1空条件运算符 (?. 和 ?[])
Section titled “空条件运算符 (?. 和 ?[])”?. 和 ?[] 运算符(C# 6+)允许你仅当变量不为 null 时才访问其成员或元素。如果变量为 null,则表达式会短路并返回 null。
string? name = null;
// 如果 name 为 null,length 将为 null。否则,它将是 name.Length。int? length = name?.Length;Console.WriteLine(length); // 输出: (空,因为 length 为 null)
name = "Alice";length = name?.Length;Console.WriteLine(length); // 输出: 5
// 也适用于数组和索引器string[]? names = { "Alice", "Bob" };string? first = names?[0]; // "Alice"
names = null;first = names?[0]; // first 变为 null,不会抛出异常始终在你的现代 C# 项目中启用可空引用类型。它是提高代码质量和防止运行时错误的最有效的单个功能之一。