C# 8中非可空引用类型运行时能否为null?跨库场景求证
你的观点完全正确!
首先得明确:C#的非可空引用类型(NRTs)本质上是编译时的静态检查机制,而非运行时的强制约束。你的例子正好戳中了这个机制的核心局限:
- 当其他未启用可空上下文的代码调用你的
Foo类时,它们处于「可空 oblivious」状态——编译器不会对这些代码里的string参数做非空校验。不管是构造函数传入null,还是后续通过Test属性赋值null,这些代码都能正常编译通过,而且运行时不会有任何内置的拦截。 - 哪怕是在启用了可空上下文的项目里,编译器也只是通过警告(可配置为错误)来提醒你可能的null风险,并非从根本上禁止null赋值。你依然可以通过强制类型转换、反射等手段绕开编译检查,把
null塞进非可空引用类型的变量里,运行时不会自动抛出异常。
那有没有运行时检查能保障非空性?答案是默认没有,必须手动实现:
- 你可以在构造函数里主动添加参数校验:
public Foo(string test) { ArgumentNullException.ThrowIfNull(test); Test = test; } - 也可以给
Test属性的setter加校验,防止后续被赋值为null:private string _test; public string Test { get => _test; set => _test = value ?? throw new ArgumentNullException(nameof(value)); }
这些手动添加的检查才是运行时层面的保障,而非可空引用类型本身不会自动提供。
内容的提问来源于stack exchange,提问作者Ilya Chernomordik
相关产品推荐
相关产品推荐

