常规OR(|)和常规AND(&)运算符是否有实际用途

时间:2015-02-13 12:02:31

标签: c# operators

我正在查看一些关于“csharp-station.com”的初学者课程来回顾我对C#的了解。对于AND和OR运算符,我总是使用“&&”和“||”像其他人一样。我甚至不知道那些版本是单一的。

说明如下:

关于OR:“两个OR形式之间的主要区别在于常规OR运算符每次都会评估两个子表达式。但是,条件OR仅在第一个子表达式求值时才会计算第二个子表达式是假的。“

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

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

那就是全部吗?是否有一个代码示例使用常规运算符更合理?我知道这个问题很简单,但我只是好奇。提前谢谢。

4 个答案:

答案 0 :(得分:2)

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

设置第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)
    ...

答案 1 :(得分: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");

将打印出不同的结果。

据说这取决于这些副作用是一个坏主意。因此,通常使用非短路逻辑运算符仅适用于被认为设计不佳的情况。因此,只要您发现需要使用它们,很可能意味着代码设计存在缺陷。

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

答案 2 :(得分:1)

他们执行二进制(基数2)计算。请参阅bitwise operations

|  OR   
&  AND
^  XOR
~  NOT

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

答案 3 :(得分:0)

这些运营商的假设情景。如前所述,所有这些都涉及副作用。

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

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

然后您的整个验证方法可能如下所示:

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