The wrapper is a "box"; re garbage collection of boxes - there is no difference as far as the grabage collector is concerned. A box is collected with exactly the same rules and treatment as any other object.
however, if a value-type overrides a method (such as ToString()
), it is not necessary to box it to call the method. Hence, value-types should (as a matter of routine) override as many of the object
methods as possible ;-p
You can see the difference in the IL (via reflector) - so for the C#:
static int GetInteger() {return 123;}
static string TestToString() {
int i = GetInteger(); // to prove no cheating
return i.ToString();
}
static Type TestGetType() {
int i = GetInteger(); // to prove no cheating
return i.GetType();
}
We have the IL:
.method private hidebysig static string TestToString() cil managed
{
.maxstack 1
.locals init (
[0] int32 i)
L_0000: call int32 Program::GetInteger()
L_0005: stloc.0
L_0006: ldloca.s i
L_0008: call instance string [mscorlib]System.Int32::ToString()
L_000d: ret
}
.method private hidebysig static class [mscorlib]System.Type TestGetType() cil managed
{
.maxstack 1
.locals init (
[0] int32 i)
L_0000: call int32 Program::GetInteger()
L_0005: stloc.0
L_0006: ldloc.0
L_0007: box int32
L_000c: call instance class [mscorlib]System.Type [mscorlib]System.Object::GetType()
L_0011: ret
}
Note that ToString()
doesn't involve a box, but GetType()
does at L_0007
(since it isn't (can't be) overridden)