如何声明带有非Nullable init访问器的Nullable属性?
如何让编译器强制约束Nullable属性的init访问器不接受null值?
我有一个带Nullable修饰的属性,当前在init访问器里手动写了null防护逻辑:
string? MyString { get { ... } init { if (value is null) return; ... } }
我希望能让编译器直接强制约束init访问器不能接收null值,不用自己写防护。试过重载属性的写法,但编译器不允许:
string? MyString { get { ... } } string MyString { init { ... } }
目前用[DisallowNull]属性只能产生警告,还是得保留null防护逻辑,有没有更好的实现方式?
方案1:结合[MaybeNull]属性分离get/init的nullable语义
可以将属性的类型声明为非nullable的string,同时给get访问器标记[MaybeNull],实现语义拆分:
- 调用init访问器时,编译器会强制要求传入非null值,无需手动写null检查
- 读取属性值时,编译器会识别到可能返回null,自动提示nullable相关的风险
代码示例:
using System.Diagnostics.CodeAnalysis; [MaybeNull] public string MyString { get { ... } // 返回值可能为null,编译器会做相应提示 init { ... } // value为非nullable string,编译器强制不能传null }
方案2:用[DisallowNull]配合将警告升级为错误
如果坚持使用string?类型的属性,可通过将nullable相关警告升级为错误,让编译器强制约束调用方不能传null,这样init里的手动防护逻辑可以移除:
- 确保项目已启用nullable上下文,在项目文件中添加:
<Nullable>enable</Nullable>
- 将
CS8625(不能将null字面量转换为非nullable引用类型)警告设为错误,项目文件中添加:
<WarningsAsErrors>CS8625</WarningsAsErrors>
- 代码中保留
[DisallowNull]属性:
using System.Diagnostics.CodeAnalysis; [DisallowNull] public string? MyString { get { ... } init { ... } // 编译器已强制value非null,无需手动检查 }
方案3:通过私有字段拆分语义
用私有nullable字段存储值,公开属性的init访问器接受非nullable参数,同时添加运行时校验(可选):
private string? _myString; public string? MyString { get => _myString; init => _myString = value ?? throw new ArgumentNullException(nameof(value)); }
这种方式下编译器会因为value是string类型(非nullable)而强制调用方不传null,同时运行时也能避免null值被存入字段。
内容的提问来源于stack exchange,提问作者onbeben
相关产品推荐
相关产品推荐

