索引器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
相关产品推荐
相关产品推荐

