Настало время для любимого всем игрового шоу: КОРОБКА ИЛИ НЕТ КОРОБКА!
public string DoIntToString(int anInt)
{
return anInt.ToString();
}
КОРОБКА или НЕТ КОРОБКИ ?Давайте перейдем к IL:
IL_0001: ldarga.s anInt
IL_0003: call instance string [mscorlib]System.Int32::ToString()
NO BOX .ToString()
- это метод virtual
для object
, который переопределяется на int
.Поскольку struct
s не может участвовать в неинтерфейсном наследовании, компилятор знает, что подклассов int
не существует, и может генерировать вызов int
версии ToString()
напрямую.
static Type DoIntGetType(int anInt)
{
return anInt.GetType();
}
BOX или NO BOX ?Давайте перейдем к IL:
IL_0001: ldarg.0
IL_0002: box [mscorlib]System.Int32
IL_0007: call instance class [mscorlib]System.Type [mscorlib]System.Object::GetType()
BOX .GetType()
равно , а не virtual
на object
, поэтому нет int
версии метода.Аргумент должен быть в штучной упаковке, и вызов выполняется для нового упакованного объекта.
private static string DoIntToStringIFormattable(int anInt)
{
return anInt.ToString(CultureInfo.CurrentCulture);
}
BOX или NO BOX ?Давайте перейдем к IL:
IL_0001: ldarga.s anInt
IL_0003: call class [mscorlib]System.Globalization.CultureInfo [mscorlib]System.Globalization.CultureInfo::get_CurrentCulture()
IL_0008: call instance string [mscorlib]System.Int32::ToString(class [mscorlib]System.IFormatProvider)
NO BOX .Несмотря на то, что ToString(IFormattable)
является реализацией интерфейса IFormatProvider
, сам вызов осуществляется непосредственно против int
.По той же причине, что и в первом методе, поле не требуется.
Итак, для последнего раунда у нас есть метод:
public int CompareIntValues(int left, int right)
{
return left.CompareTo(right);
}
Зная, что CompareTo(int)
подразумеваетсяреализации IComparable<int>
, вы делаете вызов: BOX или NO BOX ?