如果我理解正确:C# 相等运算符 ( == ) 和操作数顺序
If I understand correctly: C# Equality operator ( == ) and order of operands
有人问过类似的问题,但我不确定我是否正确理解了答案。我指的是相等运算符在一个或两个 class 中被覆盖的情况。请解释我是否正确。如果我写 if(a == b) { ... }
,则使用 "a" 的 class 的相等运算符,如果使用 if(b == a) { ... }
,则使用 class 中定义的相等运算符"b"。如果我写 if(null == a) { ... }
.
则使用 class 的相等运算符
public class Program
{
public static void Main()
{
var foo = new Foo();
if(foo == null)
{
}
if(null == foo)
{
}
}
}
public class Foo
{
public static bool operator ==(Foo a, Foo b)
{
Console.WriteLine("Foo operator == called");
return ReferenceEquals(a, b);
}
public static bool operator !=(Foo a, Foo b)
{
Console.WriteLine("Foo operator != called");
return !(a == b);
}
public override bool Equals(object obj)
{
Console.WriteLine("Foo Equals() called");
return ReferenceEquals(this, obj);
}
public override int GetHashCode()
{
Console.WriteLine("Foo GetHashCode() called");
return base.GetHashCode();
}
}
输出:
Foo operator == called
Foo operator == called
所以在这两种情况下,class Foo
的相等运算符都会被调用。
situation where the equality operator is overridden in one or both classes
我们可以这样做并测试...像下面这样的东西?
class A
{
public static bool operator == (A a, B b)
{
Console.WriteLine("A");
return false;
}
public static bool operator != (A a, B b)
{
Console.WriteLine("A");
return false;
}
public static bool operator == (B b, A a)
{
Console.WriteLine("A");
return false;
}
public static bool operator != (B b, A a)
{
Console.WriteLine("A");
return false;
}
public override bool Equals(object o)
{
return false;
}
public override int GetHashCode()
{
return 0;
}
}
class B
{
public static bool operator == (A a, B b)
{
Console.WriteLine("B");
return false;
}
public static bool operator != (A a, B b)
{
Console.WriteLine("B");
return false;
}
public static bool operator == (B b, A a)
{
Console.WriteLine("B");
return false;
}
public static bool operator != (B b, A a)
{
Console.WriteLine("B");
return false;
}
public override bool Equals(object o)
{
return false;
}
public override int GetHashCode()
{
return 0;
}
}
然后你写代码如:
A a = new A();
B b = new B();
if (a == b)
{
// ...
}
然后你得到:
CS0034 Operator '==' is ambiguous on operands of type 'A' and 'B'
这是否回答了您的问题?看一下代码,当您定义运算符 ==
时,您指定了参数的类型,编译器使用它来选择要调用的运算符。在这种情况下,它会找到两个运算符,它们的操作数 A
和 B
按此顺序排列,这会导致调用不明确(编译器不知道 - 无法决定 - 使用哪个).
If I write if(a == b) { ... }
, then equality operator of the class of "a" is used and in case of if(b == a) { ... }
is used then equality operator defined in the class of "b"
这取决于操作数的类型。如果你总是把当前 class 类型的操作符放在最前面,那就对了。例如:
void Main()
{
A a = new A();
B b = new B();
if (a == b)
{
// ...
}
}
class A
{
public static bool operator == (A a, B b)
{
Console.WriteLine("A");
return false;
}
public static bool operator != (A a, B b)
{
Console.WriteLine("A");
return false;
}
public override bool Equals(object o)
{
return false;
}
public override int GetHashCode()
{
return 0;
}
}
class B
{
public static bool operator == (B b, A a)
{
Console.WriteLine("B");
return false;
}
public static bool operator != (B b, A a)
{
Console.WriteLine("B");
return false;
}
public override bool Equals(object o)
{
return false;
}
public override int GetHashCode()
{
return 0;
}
}
输出:A
.
但是,如果以相反的顺序定义操作数的运算符...
void Main()
{
A a = new A();
B b = new B();
if (a == b)
{
// ...
}
}
class A
{
public static bool operator == (B b, A a)
{
Console.WriteLine("A");
return false;
}
public static bool operator != (B b, A a)
{
Console.WriteLine("A");
return false;
}
public override bool Equals(object o)
{
return false;
}
public override int GetHashCode()
{
return 0;
}
}
class B
{
public static bool operator == (A a, B b)
{
Console.WriteLine("B");
return false;
}
public static bool operator != (A a, B b)
{
Console.WriteLine("B");
return false;
}
public override bool Equals(object o)
{
return false;
}
public override int GetHashCode()
{
return 0;
}
}
输出:B
.
The equality operator of which class is used if I write if(null == a) { ... }
首先,让我们明确一下。 B
或任何其他 classes 与此处无关。它们不会影响此比较的结果,因为您没有在此处使用它们。那样的话就很不方便了
让我们试试:
void Main()
{
A a = new A();
if (null == a)
{
// ...
}
}
class A
{
public static bool operator == (A a, B b)
{
Console.WriteLine("A");
return false;
}
public static bool operator != (A a, B b)
{
Console.WriteLine("A");
return false;
}
public override bool Equals(object o)
{
return false;
}
public override int GetHashCode()
{
return 0;
}
}
class B
{
public static bool operator == (B b, A a)
{
Console.WriteLine("B");
return false;
}
public static bool operator != (B b, A a)
{
Console.WriteLine("B");
return false;
}
public override bool Equals(object o)
{
return false;
}
public override int GetHashCode()
{
return 0;
}
}
输出:.
我们没有得到任何输出,因为被调用的运算符是此处定义的运算符 none...相反,它使用的是默认运算符(object
的运算符)。
等等!如果我改变操作数的顺序怎么办?
void Main()
{
A a = new A();
if (null == a)
{
// ...
}
}
class A
{
public static bool operator == (B b, A a)
{
Console.WriteLine("A");
return false;
}
public static bool operator != (B b, A a)
{
Console.WriteLine("A");
return false;
}
public override bool Equals(object o)
{
return false;
}
public override int GetHashCode()
{
return 0;
}
}
class B
{
public static bool operator == (A a, B b)
{
Console.WriteLine("B");
return false;
}
public static bool operator != (A a, B b)
{
Console.WriteLine("B");
return false;
}
public override bool Equals(object o)
{
return false;
}
public override int GetHashCode()
{
return 0;
}
}
输出:A
.
现在我们在 A
上使用运算符,因为它比默认运算符更匹配操作数类型。
有人问过类似的问题,但我不确定我是否正确理解了答案。我指的是相等运算符在一个或两个 class 中被覆盖的情况。请解释我是否正确。如果我写 if(a == b) { ... }
,则使用 "a" 的 class 的相等运算符,如果使用 if(b == a) { ... }
,则使用 class 中定义的相等运算符"b"。如果我写 if(null == a) { ... }
.
public class Program
{
public static void Main()
{
var foo = new Foo();
if(foo == null)
{
}
if(null == foo)
{
}
}
}
public class Foo
{
public static bool operator ==(Foo a, Foo b)
{
Console.WriteLine("Foo operator == called");
return ReferenceEquals(a, b);
}
public static bool operator !=(Foo a, Foo b)
{
Console.WriteLine("Foo operator != called");
return !(a == b);
}
public override bool Equals(object obj)
{
Console.WriteLine("Foo Equals() called");
return ReferenceEquals(this, obj);
}
public override int GetHashCode()
{
Console.WriteLine("Foo GetHashCode() called");
return base.GetHashCode();
}
}
输出:
Foo operator == called
Foo operator == called
所以在这两种情况下,class Foo
的相等运算符都会被调用。
situation where the equality operator is overridden in one or both classes
我们可以这样做并测试...像下面这样的东西?
class A
{
public static bool operator == (A a, B b)
{
Console.WriteLine("A");
return false;
}
public static bool operator != (A a, B b)
{
Console.WriteLine("A");
return false;
}
public static bool operator == (B b, A a)
{
Console.WriteLine("A");
return false;
}
public static bool operator != (B b, A a)
{
Console.WriteLine("A");
return false;
}
public override bool Equals(object o)
{
return false;
}
public override int GetHashCode()
{
return 0;
}
}
class B
{
public static bool operator == (A a, B b)
{
Console.WriteLine("B");
return false;
}
public static bool operator != (A a, B b)
{
Console.WriteLine("B");
return false;
}
public static bool operator == (B b, A a)
{
Console.WriteLine("B");
return false;
}
public static bool operator != (B b, A a)
{
Console.WriteLine("B");
return false;
}
public override bool Equals(object o)
{
return false;
}
public override int GetHashCode()
{
return 0;
}
}
然后你写代码如:
A a = new A();
B b = new B();
if (a == b)
{
// ...
}
然后你得到:
CS0034 Operator '==' is ambiguous on operands of type 'A' and 'B'
这是否回答了您的问题?看一下代码,当您定义运算符 ==
时,您指定了参数的类型,编译器使用它来选择要调用的运算符。在这种情况下,它会找到两个运算符,它们的操作数 A
和 B
按此顺序排列,这会导致调用不明确(编译器不知道 - 无法决定 - 使用哪个).
If I write
if(a == b) { ... }
, then equality operator of the class of "a" is used and in case ofif(b == a) { ... }
is used then equality operator defined in the class of "b"
这取决于操作数的类型。如果你总是把当前 class 类型的操作符放在最前面,那就对了。例如:
void Main()
{
A a = new A();
B b = new B();
if (a == b)
{
// ...
}
}
class A
{
public static bool operator == (A a, B b)
{
Console.WriteLine("A");
return false;
}
public static bool operator != (A a, B b)
{
Console.WriteLine("A");
return false;
}
public override bool Equals(object o)
{
return false;
}
public override int GetHashCode()
{
return 0;
}
}
class B
{
public static bool operator == (B b, A a)
{
Console.WriteLine("B");
return false;
}
public static bool operator != (B b, A a)
{
Console.WriteLine("B");
return false;
}
public override bool Equals(object o)
{
return false;
}
public override int GetHashCode()
{
return 0;
}
}
输出:A
.
但是,如果以相反的顺序定义操作数的运算符...
void Main()
{
A a = new A();
B b = new B();
if (a == b)
{
// ...
}
}
class A
{
public static bool operator == (B b, A a)
{
Console.WriteLine("A");
return false;
}
public static bool operator != (B b, A a)
{
Console.WriteLine("A");
return false;
}
public override bool Equals(object o)
{
return false;
}
public override int GetHashCode()
{
return 0;
}
}
class B
{
public static bool operator == (A a, B b)
{
Console.WriteLine("B");
return false;
}
public static bool operator != (A a, B b)
{
Console.WriteLine("B");
return false;
}
public override bool Equals(object o)
{
return false;
}
public override int GetHashCode()
{
return 0;
}
}
输出:B
.
The equality operator of which class is used if I write
if(null == a) { ... }
首先,让我们明确一下。 B
或任何其他 classes 与此处无关。它们不会影响此比较的结果,因为您没有在此处使用它们。那样的话就很不方便了
让我们试试:
void Main()
{
A a = new A();
if (null == a)
{
// ...
}
}
class A
{
public static bool operator == (A a, B b)
{
Console.WriteLine("A");
return false;
}
public static bool operator != (A a, B b)
{
Console.WriteLine("A");
return false;
}
public override bool Equals(object o)
{
return false;
}
public override int GetHashCode()
{
return 0;
}
}
class B
{
public static bool operator == (B b, A a)
{
Console.WriteLine("B");
return false;
}
public static bool operator != (B b, A a)
{
Console.WriteLine("B");
return false;
}
public override bool Equals(object o)
{
return false;
}
public override int GetHashCode()
{
return 0;
}
}
输出:.
我们没有得到任何输出,因为被调用的运算符是此处定义的运算符 none...相反,它使用的是默认运算符(object
的运算符)。
等等!如果我改变操作数的顺序怎么办?
void Main()
{
A a = new A();
if (null == a)
{
// ...
}
}
class A
{
public static bool operator == (B b, A a)
{
Console.WriteLine("A");
return false;
}
public static bool operator != (B b, A a)
{
Console.WriteLine("A");
return false;
}
public override bool Equals(object o)
{
return false;
}
public override int GetHashCode()
{
return 0;
}
}
class B
{
public static bool operator == (A a, B b)
{
Console.WriteLine("B");
return false;
}
public static bool operator != (A a, B b)
{
Console.WriteLine("B");
return false;
}
public override bool Equals(object o)
{
return false;
}
public override int GetHashCode()
{
return 0;
}
}
输出:A
.
现在我们在 A
上使用运算符,因为它比默认运算符更匹配操作数类型。