我刚刚看到使用if(!(a == b))
而不是C#中更常见的if(a != b)
的代码。我想知道C#两者之间是否有区别?
答案 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)
在逻辑上和概念上都没有区别,但是,由于运算符可以重载,因此在实现上可能会有区别。
尽管这突出了编码的一般要点,但任何方法,运算符,属性,无论是什么,都应旨在精确地“按其表述”进行操作。理想情况下,在实现中应该没有任何意外,没有不一致或意外的行为。