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

如何一次性抑制CS9035规则?Required属性类配置绑定报错处理

解决C# required成员在配置绑定场景下的CS9035编译错误

问题场景

定义了带有required关键字的配置类:

public class Options
{
    [Required]
    public required string Endpoint { get; set; }
}

尝试通过手动实例化后调用Bind加载配置时,触发编译器错误:

Error CS9035: Required member 'Options.Endpoint' must be set in the object initializer or attribute constructor.

手动初始化Endpoint = null!的方式不够优雅,以下是更合理的解决方案:

解决方案

1. 采用.NET官方Options绑定机制(推荐)

直接使用框架提供的Configure或Bind扩展方法,无需手动实例化对象,框架会自动处理required成员的初始化,同时支持配置验证:

public static IServiceCollection AddOptions(this IServiceCollection services, IConfigurationSection section)
{
    // 绑定配置并注册Options实例,同时启用数据注解验证
    services.AddOptions<Options>()
        .Bind(section)
        .ValidateDataAnnotations();

    return services;
}

这种方式完全符合.NET配置最佳实践,无需绕开编译器检查,还能集成验证逻辑。

2. 给无参构造函数添加[SetsRequiredMembers]特性

在配置类的无参构造函数上标记[SetsRequiredMembers],告知编译器该构造函数会确保后续代码初始化所有required成员,从而跳过编译检查:

using System.Diagnostics.CodeAnalysis; // 需引入此命名空间

public class Options
{
    [SetsRequiredMembers]
    public Options() { }

    [Required]
    public required string Endpoint { get; set; }
}

修改后即可正常使用new Options(),后续通过section.Bind(options)赋值即可。

3. 用反射创建实例

通过Activator.CreateInstance<T>绕开编译器的required成员检查,适合必须手动实例化的场景:

public static IServiceCollection AddOptions(this IServiceCollection services, IConfigurationSection section)
{
    var options = Activator.CreateInstance<Options>();
    section.Bind(options);
    // 后续验证或注册逻辑...
    return services;
}

注意:反射会将required成员设为类型默认值(如string为null),需确保后续Bind和验证逻辑能覆盖并校验这些值。

4. 改用构造函数初始化required成员

将required成员移至构造函数参数,通过配置值直接传入初始化,同时可将属性设为只读保证不可变性:

public class Options
{
    [Required]
    public string Endpoint { get; }

    public Options(string endpoint)
    {
        Endpoint = endpoint;
    }
}

对应的扩展方法实现:

public static IServiceCollection AddOptions(this IServiceCollection services, IConfigurationSection section)
{
    var endpoint = section["Endpoint"] ?? throw new InvalidOperationException("缺少Endpoint配置项");
    var options = new Options(endpoint);
    services.AddSingleton(options);
    return services;
}

这种方式从根源上避免了required关键字的编译检查问题,同时增强了配置类的不可变性。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 15:25:19