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

索引器Getter允许空Entity参数,Setter禁止空值的实现可行性咨询

问题:索引器Getter允许传入null、Setter禁止传入null的实现方式

现有如下C#代码,定义了Field<T>类的索引器,当前Setter在运行时检查传入的Entity是否为null:

class Entity { ... }

class Field<T>
{
    T this[Entity? entity]
    {
        get
        {
            ...
        }
        set
        {
            if (entity == null)
                throw new ArgumentNullException(nameof(entity));
            ...
        }
    }
}

尝试通过重载索引器分别定义允许null的Getter和禁止null的Setter,但写法无法编译:

class Field<T>
{
    T this[Entity? entity] { get... }
    T this[Entity entity] { set... }
}

请问这种需求是否可以实现?


解答

这种需求可以实现,但不能通过重载索引器的方式达成——C#中索引器的重载仅依据参数的类型和数量来区分,引用类型的可空修饰符(?)不会构成不同的签名,所以你尝试的重载写法会被编译器判定为重复定义,无法通过编译。

下面提供两种可行的实现方案:

方案1:保持单索引器,在Setter中做非空检查

这是最直接的方式,保留单个索引器,在Setter中加入非空校验(可以用C# 10+提供的简洁写法),运行时拦截null参数:

class Entity { }

class Field<T>
{
    public T this[Entity? entity]
    {
        get
        {
            // 此处实现允许entity为null的取值逻辑
            return default!;
        }
        set
        {
            // C# 10+ 简洁写法,替代手动if判断
            ArgumentNullException.ThrowIfNull(entity);
            // 此处实现非null entity的赋值逻辑
        }
    }
}

方案2:拆分Setter为独立方法

如果希望在编译阶段就强制禁止传入null(而非运行时检查),可以把Setter逻辑抽成独立的方法,方法参数使用非可空的Entity类型,这样编译器会直接拦截null参数:

class Entity { }

class Field<T>
{
    public T this[Entity? entity]
    {
        get
        {
            // 此处实现允许entity为null的取值逻辑
            return default!;
        }
    }

    public void SetValue(Entity entity, T value)
    {
        // 编译时要求entity不能为null,无需额外检查(若需防御性编程可保留检查)
        // 此处实现赋值逻辑
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 18:20:42