2012-02-28 49 views
7

我有许多具有IsActive属性的实体。出于内部原因,我需要所有这些字段都是可空的。在另一方面,对于每个实体我可能有数十应用程序的地方做一个双重考验:避免重复测试相同属性上的空值

如果我创建一个方法类似

(空被视为真)

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

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

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

我试图找到一种方式来重写,但我当然可以返回类型不更改为纯bool

在这种情况下,您将如何避免冗余?

+5

所以在你的情况下null等价于* true *,而不是false?这有点不寻常。 – 2012-02-28 16:46:39

+0

是的,这只是“只要它不是假的,这是真的”。我同意这可能不是最佳做法! – Mathieu 2012-02-28 16:52:11

回答

13

使用GetValueOrDefault方法,指定值来替代使用的null

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

注:

是否使用CLR方法(GetValueOrDefault)或la nguage操作符(C#中的??,VB中的If(,))对结果没有影响,它只是代码一致性问题。就我个人而言,我在想要以相同方式处理可为空值的类型和字符串的地方使用语言运算符,但在我想强调可空值所发生的事情的地方使用CLR方法。

1

你为什么不只是这个隐藏实现细节中,吸气:

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

编辑:实现属性生成的,无法修改

你可以声明一个新的类型后,所谓ThreeValBool,这基本上是一个布尔值?然后添加其中的隐式转换为bool,像这样:

struct ThreeValBool 
{ 
    private bool? _value; 

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

显然,你需要添加一个方法来设置值...

使你的属性的类型(希望设计师会让你这样做)。

+0

因为该实现位于.designer.cs文件中。否则,是的,这将是一个很好的解决方案! – Mathieu 2012-02-28 16:49:32

+0

那么,你可以让IsActive生成的属性保密吗?如果是这样,你可以添加你的IsReallyActive属性。 – zmbq 2012-02-28 16:50:38

+0

似乎有点笨重,到处都有。如果这是路线,我会给AOP一点点时间,让它稍微短一些。将属性放在IsActive上以覆盖返回值。同时赋予它重用其他怪异布尔值的能力。 – 2012-02-28 16:50:42

3

如果你的财产是Nullable<>null值意味着true,你可以使用它来代替一个明确的空检查:

language.IsActive.GetValueOrDefault(true); 
2

很好的答案被给予,我会也许做一个

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

在某些静态帮助器类上。