如果第一个条件为假,假设 if-and 语句总是会中断是不是安全? [复制]

Posted

技术标签:

【中文标题】如果第一个条件为假,假设 if-and 语句总是会中断是不是安全? [复制]【英文标题】:Is it safe to assume if-and statements will always break if the first condition is false? [duplicate]如果第一个条件为假,假设 if-and 语句总是会中断是否安全? [复制] 【发布时间】:2021-08-25 01:38:18 【问题描述】:

如果我有

if (false && true) 
    ...

我可以确定每台计算机/编译器/任何东西都会执行忽略第二个条件的快捷方式吗?在我的实现中,第二个条件假设第一个为真,否则会导致致命错误。例如:

if (Foobar is BoolContainer && Foobar.BoolVar)
    ...

其中BoolContainer 是一个具有布尔属性BoolVar 的示例类。

【问题讨论】:

我建议改写“是”。不是答案。 IE。要求标准的解释或引用。 && 需要两个条件都为真才能执行if 块中的代码。所以是的,如果第一个条件不为真,那么它不会检查第二个条件并评估为假并跳过 if 块的执行。 @ChetanRanpariya 请在回答帖子中回答,而不是在 cmets 中回答。 你可能对this question感兴趣,特别是this answer 【参考方案1】:

MSDN 状态(https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/boolean-logical-operators):

条件逻辑与运算符 &&,也称为“短路”逻辑与运算符,计算其操作数的逻辑与。如果 x 和 y 都为真,则 x && y 的结果为真。否则,结果为假。如果 x 计算结果为 false,则不计算 y。

所以你的假设是正确的。虽然你在使用 & 时应该小心:

& 运算符计算其操作数的逻辑与。如果 x 和 y 的计算结果都为真,则 x & y 的结果为真。否则结果为假。

即使左侧操作数的计算结果为 false,& 运算符也会计算两个操作数,因此无论右侧操作数的值如何,运算结果都是 false。

当您使用 & 时,您可能会得到不需要的评估。

【讨论】:

所以即使我正在编写将针对不同操作系统编译的代码,这始终是一个安全的假设(只要我小心使用&& 而不是&)? @JustinIaconis C# 规范要求 && 运算符短路。任何在左侧为假时评估右侧的 C# 编译器都有错误。 C# 编译器生成 IL,因此特定平台的即时编译器应该无法撤消短路评估。【参考方案2】:

有一个extreme edge case && 不会必然做你所期望的。在普通代码中您不会遇到这种情况。 ;)

在下面的代码中,两个布尔值都将输出为True,但如果您使用&& 它们,结果将(在某些.NET 版本上,但不是全部)不是True (因为true2 是一个“不寻常的”true)。

再说一次,这不是你在现实生活中会经历的。

namespace MyNamespace

    using System;
    using System.Runtime.InteropServices;

    namespace Work
    
        [StructLayout(LayoutKind.Explicit)]
        public struct HackedBoolean
        
            [FieldOffset(0)] public int value;
            [FieldOffset(0)] public bool boolean;
            public bool GetBool(int seed)
            
                value = seed;
                return boolean;
            
        

        public class MyClassCS
        
            public static void Main(string[] args)
            
                var hacked = new HackedBoolean();
                var true1 = hacked.GetBool(1);
                var true2 = hacked.GetBool(2);

                Console.WriteLine(true1);
                Console.WriteLine(true2);
                Console.WriteLine(true1 && true2);
                Console.WriteLine(true1 == true2);

                Console.ReadLine();
            
        
    

【讨论】:

我认为这个建议可能取决于 .net fw 版本 - 如果你 && 结果将在 472 上为真,但在 .net 核心上为假 好点@CaiusJard - 已更新。【参考方案3】:

是的,它是安全的。 如果您希望双方都被评估,您可以使用 & 代替 &&。 否则在这种情况下它将跳过第二个条件。

【讨论】:

【参考方案4】:

根据条件逻辑 ANN 运算符 && on MSDN 条件的文档,使用 && 运算符仅在所有条件都为真时才为真。

如果任何条件评估为假,则整个评估结果为假。

在从左到右评估条件时,如果前一个条件为假,则不评估下一个条件。

【讨论】:

【参考方案5】:

是的,it is guaranteed by the language specification:

操作x && y 对应于操作x & y,除了y 仅在x 不是false 时才被评估。

根据我的经验,像这样的短路条件表达式的第二部分依赖于这种行为是一种非常常见的习惯用法。

您可能想知道为什么它说“不是false”而不是“true”。对于bool 类型,这两者是等价的。起初我以为是因为bool? 有一个提升的运算符来处理null,但是this is not the case。但是您可以使用重载 truefalse&| 运算符的类型来做类似的事情,实际上规范提供了 the DBBool example struct 就是这样做的。

【讨论】:

以上是关于如果第一个条件为假,假设 if-and 语句总是会中断是不是安全? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

即使第一个条件为假,是不是所有条件都在 if 语句中进行检查?

部分课后练习

IF 语句:如果条件为假,如何将单元格留空(“”不起作用)

“更改此条件,使其不会总是评估为假” - SonarQube

Opengl着色器:如果条件错误地评估为假

为啥即使条件为假,这个“IF”也总是执行?