考虑这段代码:
int a = 0;
short b = 0;
int c = 0;
object a1 = a;
object b1 = b;
object c1 = c;
Console.WriteLine(1);
//comparing primitives - int vs. short
Console.WriteLine(a == b);
Console.WriteLine(b == a);
Console.WriteLine(a.Equals(b));
Console.WriteLine(b.Equals(a));
Console.WriteLine(2);
//comparing objects - int vs. int
Console.WriteLine(c1 == a1);
Console.WriteLine(a1 == c1);
Console.WriteLine(c1.Equals(a1));
Console.WriteLine(a1.Equals(c1));
Console.WriteLine(3);
//comparing objects - int vs. short
Console.WriteLine(a1 == b1);
Console.WriteLine(b1 == a1);
Console.WriteLine(a1.Equals(b1)); //???
Console.WriteLine(b1.Equals(a1));
它打印这个输出:
1
True
True
True
False
2
False
False
True
True
3
False
False
False
False
我知道的;什么是清楚的
第2节: ==
仅当与对象一起使用时,运算符比较内存中由两个不同名称引用的一个对象(不是很常见,但可能会发生),才会返回 true。Equals()
方法比较对象的内容(值)。该网站的许多答案中都提到了这一点。
第1节: Using ==
运算符,编译器将“较小”类型转换为“较大”(short
to int
)并比较原始值。操作数(变量)的顺序并不重要。的结果Equals()
最后一行可能会令人困惑,因为它返回 false(不比较值),但它是可以理解的。这里的顺序很重要。正如本文中所了解到的answer https://stackoverflow.com/a/21273904/1474519,必须选择最佳的过载。它由第一个变量的类型选择:short.Equals(short)
。但是之后int
无法转换为“较小”类型(short
),因此没有进行比较并且方法返回 false。
问题:
- 我上面的理解正确吗?
- 为什么第 3 节的最后两行(使用
Equals()
) 都返回 false?为什么与第 1 部分第 3 行有差异?为什么不进行重载和值比较?它变得非常抽象,我找不到原因。
在第 1 节第 3 行
int a = 0;
short b = 0;
Console.WriteLine(a.Equals(b));
你称这种超载为int
: bool Equals(int other)
, 因为b
(短)可以隐式转换为int
所以选择这个重载。它返回 true。在第 3 节第 3 行
int a = 0;
short b = 0;
object a1 = a;
object b1 = b;
Console.WriteLine(a1.Equals(b1)); //???
另一个超载int
(not object
, 因为Equals
是虚拟方法)被调用:bool Equals(object other)
。让它返回 trueother
应该具有完全相同的类型(int
),但这确实是short
所以它返回 false。拳击与此处无关,您可以通过以下方式验证:
int a = 0;
int c = 0;
object a1 = a;
object c1 = c;
// yes, different objects
Console.WriteLine(a1 == c1); // false
// still equal, because both are boxed ints
Console.WriteLine(a1.Equals(c1)); // true
至于理解,我认为文档 https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/equality-comparison-operator包含所有相关信息。只要记住:
Both ==
运算符和Equals
方法可以在类中手动定义,因此理论上可以做任何事情。您的理解仅与“默认”行为有关。
==
不是常识意义上的虚拟,不像Equals
方法。所以当你这样做时a1 == b1
- ==
在编译时定义中调用(基于类型a1
and b1
),但是当你打电话时a1.Equals(b1)
- 它是虚拟调度的,因此调用的方法是在运行时定义的。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)