我刚刚看到了使用的代码,if(!(a == b))而不是if(a != b)C#中更常见的代码。我想知道C#两者之间是否有区别?
Jon*_*eet 37
在大多数情况下,它们是相同的-但并非必须如此。!=并==可以使用不同的逻辑分别过载。这是一个例子:
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
}
}
Run Code Online (Sandbox Code Playgroud)
在绝大多数情况下,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"
}
}
Run Code Online (Sandbox Code Playgroud)
这a != b是类型Test,但是!(a == b)是类型string。是的,这太可怕了,您不太可能在现实生活中碰到它-但这是C#编译器需要了解的事情。
Eri*_*ert 14
当然有区别。如果!和==和!=重载,则第一个调用前两个运算符,第二个调用第三个运算符。允许那些人做非常不同的事情,尽管这样做是愚蠢的。
实际上,实现重载==和!=运算符是很常见的。bool operator !=(C x, C y) => !(x == y);例如,您可能会说。在这种情况下,x != y将是无限递归,这与调用!(x == y)!完全不同。
从逻辑上和概念上来说,这没有什么区别,但是,由于运算符可能会过载,因此在实现上可能会有区别。
这突出了编码中的一个普遍点,即任何方法,运算符,属性,无论是什么,都应旨在准确地“按其表述”进行操作。理想情况下,在实现中不应出现任何意外,不一致或意外的行为。