You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让C#可空类型检查器知晓函数调用后变量非空?

简短版

如何让C#可空类型检查编译器意识到调用以下代码后,变量customer不可能为空:

Constraints.NotNull(customer);
详细版

如果编写如下代码:

#nullable enable

Customer? c;
...
Console.WriteLine(customer.FirstName);

编译器会(正确地)发出警告,提示访问.FirstName时customer可能为空:

customer.FirstName ⇐ 可能存在空引用

守卫约束

我希望实现一个守卫或约束,告知C# 8可空类型检查器该值不可能为空。我会调用一个能保证函数返回后变量不为空的方法:

#nullable enable

Customer? customer;
...
Constraint.NotNull(customer, nameof(customer)); // 如果该方法返回,则customer肯定不为空
Console.WriteLine(customer.FirstName);

Constraint.NotNull的实现大致如下:

public static class Constraint
{
    public static void NotNull(Object? o, String msg="")
    {
       if (o == null) 
          throw new Exception("Object cannot be null "+msg);
    }
}

该守卫能正常工作:当变量为空时抛出异常。但编译器无法识别Constraint.NotNull返回后customer不为空:
图片说明

另一个示例

在旧代码中遇到的更典型示例:

Customer? currentCustomer;

//...

EnsureCurrentCustomer(); 

DoSomethingWithIt(currentCustomer); // 因EnsureCurrentCustomer的保证,变量肯定不为空,但编译器并不知晓。

我们需要让EnsureCurrentCustomer能告知C# 8可空类型检查器,调用该函数后变量currentCustomer不可能为空。

该如何实现?


  • 尝试1:空宽恕运算符(!)
    不可行。我希望配合类型系统工作,而非隐藏潜在风险(正如微软提醒的那样)

  • 尝试2:某Stack Overflow答案(会引发新错误)

  • 尝试3:某Stack Overflow答案(不可行,见尝试1)

ChatGPT曾表示唯一方法是使用JetBrains的[NotNull]约束,但我无法访问该工具。

更新:ChatGPT4o讲解了System.Diagnostics.CodeAnalysis.NotNullAttribute的用法。文档未提及该属性可如此使用,但经示例讲解后,PSGuy的不完整答案变得清晰,我完善并采纳了该答案。感谢ChatGPT!

内容的提问来源于stack exchange,提问作者Ian Boyd

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 01:30:31