!(a == b)和a!= b之间有区别吗

时间:2019-05-14 18:01:43

标签: c#

我刚刚看到使用if(!(a == b))而不是C#中更常见的if(a != b)的代码。我想知道C#两者之间是否有区别?

3 个答案:

答案 0 :(得分:34)

在大多数情况下,它们是相同的-但是没有!===可以使用不同的逻辑分别重载。这是一个示例:

using System;

class Test
{
    // All this code is awful. PURELY FOR DEMONSTRATION PURPOSES.
    public static bool operator==(Test lhs, Test rhs) => true;
    public static bool operator!=(Test lhs, Test rhs) => true;        
    public override bool Equals(object other) => true;
    public override int GetHashCode() => 0;

    static void Main()
    {
        Test a = null;
        Test b = null;
        Console.WriteLine(a != b);    // True
        Console.WriteLine(!(a == b)); // False
    }    
}

在大多数情况下,a != b!(a == b)的行为完全相同,而a != b几乎总是清晰的。但是值得注意的是,它们可以有所不同。

它可能会变得更加病理-a != b!(a == b)甚至可能具有不同的类型。例如:

using System;

class Test
{
    // All this code is awful. PURELY FOR DEMONSTRATION PURPOSES.
    public static Test operator==(Test lhs, Test rhs) => new Test();
    public static Test operator!=(Test lhs, Test rhs) => new Test();
    public static string operator!(Test lhs) => "Negated";
    public override string ToString() => "Not negated";

    public override bool Equals(object other) => true;
    public override int GetHashCode() => 0;

    static void Main()
    {
        Test a = null;
        Test b = null;
        Console.WriteLine(a != b);    // "Not negated"
        Console.WriteLine(!(a == b)); // "Negated"
    }    
}

此处a != b的类型为Test,但是!(a == b)的类型为string。是的,这太可怕了,您不太可能在现实生活中碰到它-但这是C#编译器需要了解的事情。

答案 1 :(得分:12)

当然有区别。如果!==!=重载,则第一个调用前两个运算符,第二个调用第三个运算符。允许那些人做非常不同的事情,尽管这样做是愚蠢的。

实际上,相互实现重载==!=运算符是很常见的;例如,您可能会说bool operator !=(C x, C y) => !(x == y);。在这种情况下,x != y将是无限递归,这与调用!(x == y)完全不同!

答案 2 :(得分:7)

在逻辑上和概念上都没有区别,但是,由于运算符可以重载,因此在实现上可能会有区别。

尽管这突出了编码的一般要点,但任何方法,运算符,属性,无论是什么,都应旨在精确地“按其表述”进行操作。理想情况下,在实现中应该没有任何意外,没有不一致或意外的行为。