int
ist ein Alias für System.Int32
struct-Typ (implizit versiegelt), der ein Verfahren aufweist Int32.ToString()
und dies ist ein Verfahren, das in der zweiten Zeile des Codes aufgerufen, so dass keine Typumwandlung auftritt.
System.Int32
ist von System.ValueType
abgeleitet, die von System.Object
abgeleitet ist. Int32.ToString()
überschreibt ValueType.ToString()
, wodurch Object.ToString()
überschrieben wird.
Der beste Weg, ob Boxen überprüfen auftritt, ist IL-Code, um zu sehen (ich habe mit ILSpy worden):
using System;
namespace BoxingTest
{
class Program
{
static void Main(string[] args)
{
int i = 0;
string s1 = i.ToString();
}
}
}
zu übersetzt:
.method private hidebysig static
void Main (
string[] args
) cil managed
{
// Method begins at RVA 0x2050
// Code size 12 (0xc)
.maxstack 1
.entrypoint
.locals init (
[0] int32 i,
[1] string s1
)
IL_0000: nop
IL_0001: ldc.i4.0
IL_0002: stloc.0
IL_0003: ldloca.s i
IL_0005: call instance string [mscorlib]System.Int32::ToString()
IL_000a: stloc.1
IL_000b: ret
} // end of method Program::Main
Sie, dass keine Boxen sehen aufgetreten und dass System.Int32::ToString()
wurde aufgerufen.
Boxing hätte stattgefunden, wenn z.B. Sie haben Ihre int
zu object
explizit oder implizit gegossen. (Beachten Sie, dass die Umstellung auf object
Typ nicht der einzige Fall ist, wenn Boxen geschieht)
Explicit Casting object
eingeben:
using System;
namespace BoxingTest
{
class Program
{
static void Main(string[] args)
{
int i = 0;
string s2 = ((object)i).ToString();
}
}
}
gibt:
.method private hidebysig static
void Main (
string[] args
) cil managed
{
// Method begins at RVA 0x2050
// Code size 16 (0x10)
.maxstack 1
.entrypoint
.locals init (
[0] int32 i,
[1] string s2
)
IL_0000: nop
IL_0001: ldc.i4.0
IL_0002: stloc.0
IL_0003: ldloc.0
IL_0004: box [mscorlib]System.Int32
IL_0009: callvirt instance string [mscorlib]System.Object::ToString()
IL_000e: stloc.1
IL_000f: ret
} // end of method Program::Main
Boxen durch implizite Umwandlung:
using System;
namespace BoxingTest
{
class Program
{
static void Main(string[] args)
{
int i = 0;
object o = i;
string s3 = o.ToString();
}
}
}
ergibt:
.method private hidebysig static
void Main (
string[] args
) cil managed
{
// Method begins at RVA 0x2050
// Code size 18 (0x12)
.maxstack 1
.entrypoint
.locals init (
[0] int32 i,
[1] object o,
[2] string s3
)
IL_0000: nop
IL_0001: ldc.i4.0
IL_0002: stloc.0
IL_0003: ldloc.0
IL_0004: box [mscorlib]System.Int32
IL_0009: stloc.1
IL_000a: ldloc.1
IL_000b: callvirt instance string [mscorlib]System.Object::ToString()
IL_0010: stloc.2
IL_0011: ret
} // end of method Program::Main
In allen drei Fällen Saiten Wert haben "0"
weil Object.ToString()
die ursprüngliche Art der boxed Variable kennt und nennt ToString() `dieses Typs.
Dies ist der IL-Code des Object.ToString()
:
.method public hidebysig newslot virtual
instance string ToString() cil managed
{
.custom instance void __DynamicallyInvokableAttribute::.ctor() = (
01 00 00 00
)
// Method begins at RVA 0x2052
// Code size 12 (0xc)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance class System.Type System.Object::GetType()
IL_0006: callvirt instance string System.Object::ToString()
IL_000b: ret
} // end of method Object::ToString
nicht zuerst und nicht die zweite. Da das 'int' von' object' abgeleitet ist, hat es 'ToString()' überladen. –
Hier ist kein Boxing involviert –