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

C#中如何为GetOrNew的Func参数配置NotNullIfNotNull规则

解决方案

针对你提到的委托参数可空性关联的需求,有两种常用实现方式:

方案1:.NET 7+ 直接使用特性标注

.NET 7 扩展了[NotNullIfNotNull]特性的适用范围,支持直接标注委托类型的参数,明确关联GetOrNew的key参数和factory委托的入参的可空性:

using System.Diagnostics.CodeAnalysis;

public class X {
    public T GetOrNew<T, TKey>(TKey? key, [NotNullIfNotNull(nameof(key))] Func<TKey?, T> factory){
        // 原有代码逻辑完全不变
        var instance = factory(key);
        return instance;
    }
}

该标注会告诉编译器规则:当传入GetOrNew的key不为null时,factory的入参也一定不为null。你的两种调用场景都能完美适配:

  • 传入非空key时,编译器会自动判定factory的入参非空,调用index.GetRandomPerson()不会触发警告
  • 传入null作为key时,factory的入参仍判定为可空,符合你的兼容要求

方案2:重载方案(兼容.NET 6及更早版本)

如果你的项目需要兼容更低版本的.NET运行时,可以通过方法重载实现同样的效果,不需要修改原有核心逻辑:

public class X {
    // 非空key的重载,供key不为null的场景调用
    public T GetOrNew<T, TKey>(TKey key, Func<TKey, T> factory) where TKey : notnull
    {
        // 内部复用可空版本的实现,用!抑制非空警告(逻辑上已经保证key非空)
        return GetOrNew(key, k => factory(k!));
    }

    // 原有可空key的重载,供key可能为null的场景调用
    public T GetOrNew<T, TKey>(TKey? key, Func<TKey?, T> factory){
        // 原有代码逻辑完全不变
        var instance = factory(key);
        return instance;
    }
}

编译器会根据你传入的key的可空性自动匹配对应重载:

  • 传入非空key时匹配第一个重载,factory的入参直接声明为非空,无警告
  • 传入null作为key时匹配第二个重载,factory的入参为可空类型,符合使用需求

两种方案都不需要修改你现有的调用代码,也完全保留了GetOrNew支持传入null作为合法参数的能力。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 19:24:05