检查条件表达式中可为 null 的布尔值的最佳方法(如果 ...)[已结束]

Best way to check for nullable bool in a condition expression (if ...) [closed]

提问人:FireSnake 提问时间:4/20/2010 更新时间:10/27/2020 访问量:223552

问:


想改进这个问题吗?更新问题,以便可以通过编辑这篇文章来用事实和引文来回答。

3年前关闭。

我想知道对可为 null 的布尔值进行条件检查的最干净、最易于理解的语法是什么。

以下编码风格是好是坏?有没有办法更好/更干净地表达病情?

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

尤其是 if (nullableBool ?? false) 部分。我不喜欢这种风格......if (x.HasValue && x.Value)

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

C# 编码样式 可为 null

评论

2赞 Masoud 7/23/2020
从 C# 7.0 开始,可以将 is 运算符与类型模式一起使用,以检查 null 的可为 null 值类型的实例,并检索基础类型 int 的值:int?a = 42;if (a is int valueOfA) {

答:

0赞 James Westgate 4/20/2010 #1

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

可为 null 的布尔类型的另一点是它是三态的,因此当它只是 null 而不是默认为 false 时,您可能希望执行其他操作。

65赞 Dan Diplo 4/20/2010 #2

你可能不喜欢它,但我个人发现

if (x.HasValue && x.Value)

可读性最强。它清楚地表明您正在使用可为 null 的类型,并清楚地表明您首先检查可为 null 的类型是否具有值,然后再有条件地对它执行操作。

如果你采用你的版本并用 x 替换变量,它也会显示:

if (x ?? false)

有那么清楚吗?很明显 x 是可为 null 的类型吗?我会让你决定的。

评论

1赞 FireSnake 4/20/2010
阿法克,??仅适用于可为 null 的类型。另外,变量的名称应该比 x 更好:)
6赞 Dan Diplo 4/20/2010
我所说的“可为空类型”是指 System.Nullable 类型。任何引用类型都可以为 null。此外,如果您需要使用变量的类型作为其名称的一部分,则表明您的代码不清楚。
0赞 Prashant Yadav 8/5/2019
@DanDiplo UT怎么写?
0赞 nothingisnecessary 10/25/2019
x在上下文中很好,有时更干净;机智:var openOrders = orders.Where(x=>x.Open ?? false)
0赞 The incredible Jan 9/21/2022
if (x ?? false) = if(x==true).我喜欢“??”,但不喜欢布尔值。🙂
30赞 Oded 4/20/2010 #3

如果你想把 a 视为 false,那么我会说最简洁的方法是使用 null 合并运算符 (),如您所述:null??

if (nullableBool ?? false) { ... }
10赞 Andrey Frolov 4/20/2010 #4

使用扩展。

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
}

评论

1赞 Thibault Falise 4/20/2010
如果你想考虑作为?nulltrue
1赞 Andrey Frolov 4/20/2010
IsTrue() |IsNull()..:)我重现了 SQL 如何处理 null 的逻辑。我认为这是最干净、最容易理解的语法。
0赞 Michael Freidgeim 8/23/2010
它应该是公共静态 bool IsFalse(this System.Nullable val) { return !val ?? true; } 将 null 视为 false
2赞 glenn garson 8/28/2014
在最后两个方法(即 IsNull 和 IsNotNull)中,它可能缺少分号 (;)
108赞 Lucero 4/20/2010 #5

如何使用 GetValueOrDefault,这是不言自明的,并允许使用您想要的任何默认值:

if (nullableBool.GetValueOrDefault(false)) {
}

评论

9赞 Nano Taboada 12/28/2012
根据此方法可能引发的上下文System.NotSupportedException: LINQ to Entities does not recognize the method 'Boolean GetValueOrDefault()' method, and this method cannot be translated into a store expression.
3赞 paultechguy 3/17/2018
我喜欢这种方法,因为它也适用于非 if 语句(即赋值)。
0赞 Gopher 4/20/2010 #6

给定枚举

public enum PublishMode { Edit, View }

你可以像这里一样做

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

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

评论

0赞 ToolmakerSteve 7/8/2015
不是这个问题的答案,具体来说是关于.nullable boolean
497赞 Artiom Chilaru 4/20/2010 #7

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

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?为 null :P

评论

10赞 Micah Zoltu 10/18/2015
我没有意识到可为空的比较像这样有意义。详情请见 msdn.microsoft.com/en-us/library/2cf62fcy.aspx
13赞 Eric Mutta 3/18/2021
文档的相关部分:For the equality operator ==, if both operands are null, the result is true, if only one of the operands is null, the result is false; otherwise, the contained values of operands are compared.
1赞 controlbox 2/20/2022
虽然永远不会返回 true,如果它是 ,则不能考虑可为 null 的布尔值中的 null 值,并且运算符在用于可为 null 的布尔值时将无法编译,我个人觉得这有点痛苦,因为在布尔条件的上下文中,任何不可以考虑的东西都可以考虑,同时仍然允许对 null 值本身进行相等检查以返回 true。(nullableBool == true)nullfalse&&||truefalse
0赞 The incredible Jan 9/21/2022
@controlbox我认为你不对。布尔值表示 0 = false,其他一切都为 true。也许这就是他们不允许我无法想象自愿使用可为空布尔值的原因。我讨厌用“也许”来回答“是或否”的问题。🙂if (nullableBool) ...
0赞 controlbox 9/26/2022
@TheincredibleJan 如果 null 被视为“值”,我会同意,但事实并非如此(因此.HasValue() 返回 false),因此在布尔表达式的上下文中,true 是唯一的非 false 值,因此 null(没有值)也不能被视为 true。
0赞 user4593252 1/31/2015 #8

如果您无法控制条件的一部分是否正在检查可为 null 值,则始终可以尝试以下操作:

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

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

当然,这是一种手动的说法GetValueOrDefault(false)

评论

3赞 Servy 1/31/2015
OP 中提供的解决方案是一回事,只是代码膨胀要少得多。这根本不有利。
8赞 Sz. Moncz 4/14/2016 #9

让我们检查一下与 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) ...

评论

0赞 IronHide 5/10/2018
我只是想知道为什么我们不能这样做,如果(可空)....这将是处理,但需要谨慎对待if(nullable)...else if(!nulllable)...else..
0赞 Sz. Moncz 5/18/2018
我想说的是,在过去几年中,编码风格(由于 stylecop、分析器等工具的可用性)越来越倾向于明确、清晰、“意图确认”代码(例如,建议使用不需要的括号只是为了确认运算符优先级的预期用途,或使用各种注释/合同系统)。IMO 引入这样的语法会造成更多的混乱,因为如何处理 null 的程度比好处要少得多。
21赞 user1023602 12/21/2016 #10

想想布尔?由于有 3 个值,那么事情就变得更容易了:

if (someNullableBool == true)     // only if true
if (someNullableBool == false)    // only if false
if (someNullableBool == null)     // only if null
3赞 ds4940 9/13/2017 #11

如果你只想测试 / ,我刚刚使用并且读得很好的一个是truenullfalse

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

评论

2赞 Chase Florell 2/26/2020
你在这里没有得到一个空引用异常吗?
0赞 ds4940 2/26/2020
@ChaseFlorell我不得不在VS Interactive窗口中仔细检查这一点。所以要记住的是,somecondition 的类型是 Nullable<bool>。您仍然可以调用从对象继承的方法(如 Equals)、HasValue 和 GetValueOrDefault,但不能调用 Value
1赞 Chase Florell 2/26/2020
有趣的是,我现在可以看到了。对于引用类型来说仍然很粗略 dotnetfiddle.net/8cAI21
12赞 Zze 3/20/2018 #12

实际上,我认为这是一个合理的选择,尤其是当您尝试在 linq 中计算可为 null 的布尔值时。(nullableBool ?? false)

例如:

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)

评论

0赞 The incredible Jan 9/21/2022
为什么不只是 ?:)(nullableBool == true)
49赞 Vladimir Shiyanov 10/21/2020 #13

另一种方法是使用常量模式匹配

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

与运算符不同,在读取代码时,这将区分可为 null 的类型检查和普通的“带有气味的代码”。==