任何人都可以解释这个吗?
void Main()
{
int a = 1;
short b = 1;
Console.WriteLine(b.Equals(a)); // false
Console.WriteLine(a.Equals(b)); // true
Test<int, short>(a, b); // prints: false, false
Test(a, b); // prints: false, false
}
void Test<T1, T2>(T1 x, T2 y)
{
Console.WriteLine(y.Equals(x));
Console.WriteLine(x.Equals(y));
}
(我不会在没有添加更多文字的情况下发帖,所以这里还有更多......)
答案 0 :(得分:3)
您的三个电话会回复false
,因为他们会拨打Object.Equals(Object)
。
您将盒装Int32
与装箱Int16
(short
)进行比较,因此他们会选择两个不相等的对象并返回false。
Equals(Object)
的{{3}}首先检查他们收到的盒装对象是否具有相同的确切类型,Int16
不是。
a.Equals(b)
调用overrides,在编译时隐式地将b
转换为Int32
。
因此,该方法看到两个具有相同值的Int32
并返回true。
答案 1 :(得分:2)
IL显示:第一个电话被装箱:
IL_0000: nop
IL_0001: ldc.i4.1
IL_0002: stloc.0 // a
IL_0003: ldc.i4.1
IL_0004: stloc.1 // b
IL_0005: ldloca.s 01 // b
IL_0007: ldloc.0 // a
IL_0008: box System.Int32
IL_000D: call System.Int16.Equals
IL_0012: call System.Console.WriteLine
IL_0017: nop
IL_0018: ret
第二个不是:
IL_0000: nop
IL_0001: ldc.i4.1
IL_0002: stloc.0 // a
IL_0003: ldc.i4.1
IL_0004: stloc.1 // b
IL_0005: ldloca.s 00 // a
IL_0007: ldloc.1 // b
IL_0008: call System.Int32.Equals
IL_000D: call System.Console.WriteLine
IL_0012: nop
IL_0013: ret
为通用方法生成的IL始终是装箱:
Test<T1,T2>:
IL_0000: nop
IL_0001: ldarga.s 02
IL_0003: ldarg.1
IL_0004: box T1
IL_0009: constrained. T2
IL_000F: callvirt System.Object.Equals
IL_0014: call System.Console.WriteLine
IL_0019: nop
IL_001A: ldarga.s 01
IL_001C: ldarg.2
IL_001D: box T2
IL_0022: constrained. T1
IL_0028: callvirt System.Object.Equals
IL_002D: call System.Console.WriteLine
IL_0032: nop
IL_0033: ret
并且使用以下方法调用此方法:
IL_0000: nop
IL_0001: ldc.i4.1
IL_0002: stloc.0 // a
IL_0003: ldc.i4.1
IL_0004: stloc.1 // b
IL_0005: ldarg.0
IL_0006: ldloc.0 // a
IL_0007: ldloc.1 // b
IL_0008: call Test<Int32,Int16>
IL_000D: nop
IL_000E: ret
所以,即使在编译时已知类型,值仍将被装箱。