【问题标题】:Is there a practical use for regular OR (|) and regular AND (&) operator常规 OR (|) 和常规 AND (&) 运算符是否有实际用途
【发布时间】:2015-02-13 12:02:30
【问题描述】:

我正在“csharp-station.com”上查找一些初学者课程,以复习我的 C# 知识。对于 AND 和 OR 运算符,我一直使用“&&”和“||”像其他人一样。我什至不知道有一个版本。

声明如下:

关于 OR:“两种 OR 形式的主要区别在于,正则 OR 运算符每次都会计算两个子表达式。但是,只有当第一个子表达式计算时,条件 OR 才会计算第二个子表达式为假。”

关于 AND:“两者的区别在于,常规的 AND 运算符每次都会计算两个表达式。但是,条件 AND 运算符只有在第一个子表达式的计算结果为 true 时才会计算第二个子表达式。”

它总结为:“条件运算符(&& 和 ||)通常被称为短路运算符,因为它们并不总是评估整个表达式。因此,它们也被用来通过忽略不必要的逻辑来生成更高效的代码。”

就这样吗?是否有一个代码示例更合理地使用常规运算符?我知道这个问题是微不足道的,但我只是好奇。提前致谢。

【问题讨论】:

  • 您是否在问为什么要在逻辑、非短路上下文中使用&/|?如果是这样,请参阅 stackoverflow.com/questions/9264897/…(它的 Java 但适用于此处)
  • 它们在充当位运算符的整数上非常有用。我一直在加密代码中使用它们。

标签: c# operators


【解决方案1】:

正如您所说,这些运算符不会短路。但这还不是全部:它们用于位操作。一些例子:

设置第 4 位:

// 00000010 | 00001000 == 00001010
value = value | (1 << 3);

清除第 4 位:

// ~00001000 == 11110111
// 00001010 & 11110111 == 00000010
value = value & ~(1 << 3);

检查第 4 位是否设置:

// 00001010 & 00001000 == 00001000
if ((value & (1 << 3)) != 0)
   ...

在 C# 中,这通常与标志枚举一起使用(enum 类型应用了[Flags] 属性)。

这是框架中的一个示例:

[Flags]
public enum FileAttributes
{
    ReadOnly = 0x1,
    Hidden = 0x2,
    System = 0x4,
    Directory = 0x10,
    Archive = 0x20,
    Device = 0x40,
    Normal = 0x80,

    // and so on...
}

因此,例如,您可以使用以下代码测试文件是否隐藏:

if ((attributes & FileAttributes.Hidden) != 0)
    ...

【讨论】:

    【解决方案2】:

    主要区别在于表达式是否有副作用以及是否希望这些副作用总是发生

    public bool A()
    {
        Console.WriteLine("A");
        return true;
    }
    
    public bool B()
    {
        Console.WriteLine("B");
        return false;
    }
    

    以上方法如下

    if(A() || B())
        Console.WriteLine("A or B");
    

    还有这个

    if(A() | B())
        Console.WriteLine("A or B");
    

    会打印出不同的结果。

    也就是说,依赖这些副作用是一个坏主意。因此,一般来说,非短逻辑运算符的使用仅适用于被认为设计不佳的情况。所以,任何时候你发现你需要使用它们很可能意味着代码的设计存在缺陷。

    但正如其他人所提到的,&amp;| 运算符也用于按位“AND”和“OR”,这与将它们与 bool 表达式一起使用不同。

    【讨论】:

    • 但是如果你执行AB的副作用,你应该把它们放在自己的语句中。
    • @CodesInChaos 我并不是说这是最佳实践,只是这就是区别所在。
    • OP 知道其中的区别,但想知道您为什么要使用非短路变体。
    • @CodesInChaos OP 引用了网站的描述。如果 OP 理解表达式可能会产生副作用,这并不是 100% 清楚的。这真的是唯一一次它会有所不同,无论这是否是糟糕的设计。但我为此添加了免责声明。
    【解决方案3】:

    它们执行二进制(以 2 为底)计算。见bitwise operations

    |  OR   
    &  AND
    ^  XOR
    ~  NOT
    

    这些是所有计算机都使用的基本机器操作。
    计算机喜欢它们,但大多数程序员更喜欢十进制算术和枚举。

    【讨论】:

      【解决方案4】:

      这些运营商有一些假设场景。如前所述,它们都涉及副作用。

      想象一下,您有一个包含usernamepasswordconfirmation 字段的网络注册表单。

      您应该在 POST 之后验证用户的输入。您计划使用返回 bool, f.e. 的简单验证方法。 IsUsernameAvailableIsUsernameValidIsPasswordComplexEnoughArePasswordAndConfirmationEquals。所有这些方法都有一个包含错误消息的输入/输出参数IList&lt;string&gt;

      那么您的整个验证方法可能如下所示:

      private bool ValidateAll(IList<string> errorMessages)
      {
          return IsUsernameAvailable(errorMessages)
               | IsUsernameValid(errorMessages)
               | IsPasswordComplexEnough(errorMessages)
               | ArePasswordAndConfirmationEquals(errorMessages);
      }
      

      【讨论】:

      • 在这种情况下,我宁愿使用return !errorMessages.Any()
      猜你喜欢
      • 2011-10-29
      • 1970-01-01
      • 2017-01-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-02
      相关资源
      最近更新 更多