在值类型上调用对象函数会导致自动装箱吗?
本文关键字:类型 调用 函数 对象 | 更新日期: 2023-09-27 18:11:34
在c#中,对一个值类型调用对象函数,如Equals()和ToString(),是否意味着编译器将自动装箱来执行该操作?如。自动装箱会在以下代码中发生吗?
int x=2;
int y=7;
bool isEqual = x.Equals(y);
No.
static void DoIt()
{
int x = 2;
int y = 7;
bool isEqual = x.Equals(y);
Console.WriteLine(isEqual);
}
将成为:
IL_0002: stloc.0
IL_0003: ldc.i4.7
IL_0004: stloc.1
IL_0005: ldloca.s x
IL_0007: ldloc.1
IL_0008: call instance bool [mscorlib]System.Int32::Equals(int32)
IL_000d: stloc.2
IL_000e: ldloc.2
IL_000f: call void [mscorlib]System.Console::WriteLine(bool)
不存在box
IL操作码,因此不发生装箱。
你可以看到它调用Int32. equals (Int32)方法,它不需要任何装箱-它接受未装箱的Int32结构体作为参数。还有Int32.Equals(Object) -这个将要求装箱。
如果一个类型实现了IEquatable<T>
,那么将选择更好的重载分辨率,更好的意思是更具体。在这种情况下,int
覆盖Equals
,因此不会发生装箱。如果接口没有实现,它将使用object.Equals
来自c#规范:
7.4.2.2更好的函数成员给定一个参数列表A,其参数类型为{A1, A2,…, AN}和两个适用的函数成员MP和MQ,参数类型为{P1, P2,…, PN}和{Q1, Q2,…, QN}, MP被定义为比MQ更好的函数成员,如果:
- 对于每个参数,从AX到PX的隐式转换并不比从AX到QX的隐式转换差,并且
- 对于至少一个参数,从AX到PX的转换优于从AX到QX的转换。
在执行此求值时,如果MP或MQ的展开形式适用,则PX或QX指的是参数列表展开形式的参数。
在这种情况下没有,因为int实现了IEquatable<int>
并且这里调用的是IEquatable<int>
的Equals,而不是Object的