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

C#中带空值检查的init属性访问器及消除可空分析警告

在C#可空引用类型中实现带输入验证的init访问器(无CS8618警告)

问题背景

启用可空引用类型的C#项目中,给属性添加init访问器并做输入验证(比如空值检查)时会遇到两难:自动属性的init无法嵌入验证逻辑;改用私有 backing field 后,编译器会抛出CS8618警告(非可空字段未初始化),但又不想通过编译指令抑制警告或使用! null原谅运算符。

解决方案

方法一:通过构造函数初始化字段(兼容C# 9+)

显式定义构造函数,通过给属性赋值间接初始化backing field,从根源避免未初始化警告,同时保留init访问器的验证逻辑:

public class User
{
    private string _username;

    public string Username
    {
        get => _username;
        init
        {
            _username = value ?? throw new ArgumentNullException(nameof(value), "用户名不能为空");
        }
    }

    // 带参构造函数强制初始化属性
    public User(string username)
    {
        Username = username;
    }

    // 若需要无参构造,可结合C# 11的required属性
    public User() { }
}

如果使用C# 11及以上版本,给Username属性添加required修饰符,即使有无参构造,编译器也会强制调用方在对象初始化时设置该属性,确保字段被正确初始化。

方法二:使用MemberNotNull特性(兼容C# 8+)

通过[MemberNotNull]特性告诉编译器,init访问器执行后会确保backing field非空,直接消除CS8618警告:

using System.Diagnostics.CodeAnalysis;

public class Product
{
    private string _productName;

    public string ProductName
    {
        get => _productName;
        [MemberNotNull(nameof(_productName))]
        init
        {
            _productName = value ?? throw new ArgumentNullException(nameof(value), "产品名称不能为空");
        }
    }

    // 无参构造也不会触发警告
    public Product() { }
}

这个特性明确告知编译器,执行init访问器后_productName字段一定处于非空状态,无需额外初始化代码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 20:20:04