在条件表达式中检查可空bool值的最佳方法(if…)

我想知道对可空bool进行条件检查的最干净和最容易理解的语法是什么。

下面的编码风格是好还是坏?有没有更好/更清楚地表达这种情况的方法?

bool? nullableBool = true;
if (nullableBool ?? false) { ... }
else { ... }

特别是if (nullableBool ??假)部分。我不喜欢if (x.HasValue && x.Value)样式…

(不确定以前是否有人问过这个问题……在搜索中找不到类似的东西)

195607 次浏览

我想这取决于你。我当然认为.HasValue方法更具可读性,特别是对于不熟悉??语法。

可空布尔类型的另一点是,它是三态的,所以当它只是空时,而不是默认为false时,您可能想做一些其他事情。

你可能不喜欢,但我个人觉得

if (x.HasValue && x.Value)

最易读。它清楚地表明,您正在使用一个可空类型,并且清楚地表明,在有条件地对可空类型进行操作之前,您首先检查该可空类型是否有值。

如果你把你的版本用x替换变量,它也是:

if (x ?? false)

清楚吗?显然x是一个可空类型吗?我会让你决定的。

如果你想将null视为false,那么我会说最简洁的方法是使用空合并操作符(??),正如你所描述的:

if (nullableBool ?? false) { ... }

使用扩展。

public static class NullableMixin {
public static bool IsTrue(this System.Nullable<bool> val) {
return val == true;
}
public static bool IsFalse(this System.Nullable<bool> val) {
return val == false;
}
public static bool IsNull(this System.Nullable<bool> val) {
return val == null;
}
public static bool IsNotNull(this System.Nullable<bool> val) {
return val.HasValue;
}
}




Nullable<bool> value = null;
if(value.IsTrue()) {
// do something with it
}

使用GetValueOrDefault怎么样,它是自解释的,允许使用任何你想要的默认值:

if (nullableBool.GetValueOrDefault(false)) {
}

鉴于枚举

public enum PublishMode { Edit, View }

你可以像这样做

 void MyMethod(PublishMode? mode)
{
var publishMode = mode ?? PublishMode.Edit;


//or
if (mode?? PublishMode.Edit == someValue)
....
}

我认为很多人都专注于这个值是可空的,而没有考虑他们真正想要的是什么:)

bool? nullableBool = true;
if (nullableBool == true) { ... } // true
else { ... } // false or null

或者如果你想要更多的选择…

bool? nullableBool = true;
if (nullableBool == true) { ... } // true
else if (nullableBool == false) { ... } // false
else { ... } // null

(nullableBool == true)将永远不会返回true,如果bool?null:P

如果你无法控制条件的一部分是否检查一个空值,你总是可以尝试以下方法:

if( someInt == 6 && someNullableBool == null ? false : (bool)someNullableBool){
//perform your actions if true
}

我知道在if语句中放入三元并不是一种纯粹的方法,但它确实清晰地解决了这个问题。

当然,这是一种手动表示GetValueOrDefault(false)的方式

让我们检查一下如何定义与null的比较:

static void Main()
{
Console.WriteLine($"null != null  => {null != null}");
Console.WriteLine($"null == null  => {null == null}");
Console.WriteLine($"null != true  => {null != true}");
Console.WriteLine($"null == true  => {null == true}");
Console.WriteLine($"null != false => {null != false}");
Console.WriteLine($"null == false => {null == false}");
}

结果是:

null != null  => False
null == null  => True
null != true  => True
null == true  => False
null != false => True
null == false => False

所以你可以安全地使用:

// check if null or false
if (nullable != true) ...


// check if null or true
if (nullable != false) ...


// check if true or false
if (nullable != null) ...

想想bool?如果有3个值,事情就会变得简单:

if (someNullableBool == true)     // only if true
if (someNullableBool == false)    // only if false
if (someNullableBool == null)     // only if null

如果你只想针对null/false测试true,我刚刚使用的一个读起来很好是

bool? someCondition = null
if (someCondition.Equals(true))
...

实际上,我认为(nullableBool ?? false)是一个合理的选项,特别是当你试图在linq中计算一个可空bool值时。

例如:

array.Select(v => v.nullableBool ?? false)
(from v in array where v.nullableBool ?? false)

在我看来更干净相对于:

array.Select(v => v.nullableBool.HasValue ? v.nullableBool.Value : false)
(from v in array where v.nullableBool.HasValue ? v.nullableBool.Value : false)

另一种方法是使用固定模式匹配:

if (nullableBool is true) {}
if (nullableBool is false) {}
if (nullableBool is null) {}

与操作符==不同,当读取代码时,这将区分可空类型检查与普通的“带有气味的代码”。