Microsoft 正在向 C# 8 添加一项名为可空引用类型的新功能。起初这令人困惑,因为所有引用类型都是可空的……那么这有什么不同呢?今后,如果启用该功能,引用类型将是不可空的,除非您明确将其标记为可空。
让我来解释一下。
可空引用类型
启用可空引用类型后,当编译器认为引用类型可能为空时,它会向您发出警告。您将看到来自 Visual Studio 的警告消息:
以及构建警告:
要消除此警告,请在引用类型后面添加问号。例如:
public string StringTest()
{
string? notNull = null;
return notNull;
}
现在引用类型的行为与 C# 8 之前相同。
通过在任何 C# 文件的顶部添加 <span class="inline-code"> #nullable enable </span> 或在 .csproj 文件中添加 <span class="inline-code">lt;NullableReferenceTypes>true</NullableReferenceTypes></span> 来启用此功能。默认情况下未启用,这是一件好事,因为如果启用了,任何现有代码库可能会像圣诞树一样闪闪发光。
空值辩论
Microsoft 现在为什么要添加此功能?空值从一开始就是该语言的一部分。老实说,我不知道为什么。我一直使用空值,这是 C# 中生活的事实。我没有意识到不使用空值是一个选项……也许没有空值的生活会更好。我们拭目以待。
您应该还是不应该使用空值?我已经总结了我所理解的正在进行的辩论。
支持
支持空值的论点通常是对象处于未知状态。这个未知状态用 null 表示。您可以在 SQL Server 的 bit 数据类型中看到这一点,它有 3 个值:null(未设置)、0 和 1。您也可以在 UI 中看到这一点,有时需要知道用户是否触及了某个字段。有人可能会反驳说:“与其使用 null,为什么不创建一个未知状态类型或’未设置’状态?“这与 null 有什么不同?您仍然需要检查这个额外的状态。现在您为每个实例创建未知状态。为什么不直接使用 null 并拥有一个全局未知状态呢?
反对
反对空值的论点是它是一种不同的数据类型,每次使用引用类型时都必须检查它。最终结果是这样的代码:
var user = GetUser(username, password);
if(user != null)
{
DoSomethingWithUser(user);
} else
{
SetUserNotFoundErrorMessage()
}
如果 GetUser 方法在所有情况下都返回用户,包括找不到用户时。如果代码从不返回 null,那么防守它是浪费,理想情况下,这会简化代码。但是,在某个时刻,您需要检查空用户并显示错误消息。不使用 null 不会消除填充用户未找到业务案例的需要。
这个功能是个好主意吗?
此功能的目的不是消除空值的使用,而是提出问题:“有没有更好的方法?“有时答案是”没有”。如果我们能通过一点预见来消除对空值的持续检查,这反过来会简化我们的代码。我赞成。好消息是 C# 使处理空值变得微不足道。
我确实担心有些人会采取教条立场,坚持消除空值,这对系统有害。这是一个愚蠢的错误,因为空值是 C# 的组成部分。
可空引用类型是个好主意吗?如果最终结果是更简单、更不容易出错的代码,那就是。
作者:Chuck Conway 是一位 AI 工程师,拥有近 30 年的软件工程经验。他构建实用的 AI 系统——内容管道、基础设施代理和解决实际问题的工具——并分享他沿途的学习成果。在社交媒体上与他联系:X (@chuckconway) 或访问他的 YouTube 和 SubStack。