避免在相同的属性上重复测试null

本文关键字:测试 null 属性 | 更新日期: 2023-09-27 18:26:07

我有许多具有IsActive属性的实体。出于内部原因,我需要所有这些字段都可以为null。另一方面,对于每个实体,我可能必须在应用程序的几十个地方进行双重测试:

(空视为真)

if (language.IsActive == null || language.IsActive.value)

如果我创建一个类似的方法

class Language
{
   public bool IsActiveLanguage()
   {
       return language.IsActive == null || language.IsActive.value;
   }
}

它仍然不会隐藏属性(至少在类内部),所以它很容易出错。

我试图找到一种重写的方法,但当然不能将返回类型更改为普通的bool

在这种情况下,你会怎么做才能避免冗余?

避免在相同的属性上重复测试null

您可以使用null合并运算符,因此您的示例将变为:

return language.IsActive ?? true;

使用GetValueOrDefault方法,指定要用于代替null:的值

public bool IsActiveLanguage()
{
    return language.IsActive.GetValueOrDefault(true);
}

注意:

是使用CLR方法(GetValueOrDefault)还是使用语言运算符(C#中的??,VB中的If(,))对结果没有影响,这只是代码一致性的问题。就我个人而言,我在希望以相同方式处理可为null的值类型和字符串的地方使用语言运算符,但在希望确切强调可为null值发生了什么的地方使用CLR方法。

如果您的属性是Nullable<>,而null的值表示true,则可以使用它而不是显式的null检查:

language.IsActive.GetValueOrDefault(true);

如果答案很好,我可能会做

public static bool IsActive(bool? toCheck)
{
   return toCheck.GetValueOrDefault(true);
}

在某个静态助手类上。

为什么不在getter:中隐藏这个实现细节

private bool? _IsActive;
public bool IsActive { get { return !_IsActive.HasValue ||_IsActive; } }

编辑:在意识到属性已生成且不能修改之后

你可以声明一个新的类型,称为ThreeValBool,它本质上是一个bool?,并添加一个从它到bool的隐式强制转换,如下所示:

struct ThreeValBool
{
    private bool? _value;
    public static implicit operator bool(ThreeValBool tvb)
    {
        return !tvb._value.HasValue || tvb.value;
    }
}

显然,您需要添加一种设置值的方法。。。

制作该类型的属性(希望设计者会允许您这样做)。