Is boxing involved when calling ToString for integer types?
Asked Answered
C

6

18

Very simple question:

int a = 5;
string str = a.ToString();

Since ToString is a virtual method of System.Object, does it mean that everytime I call this method for integer types, a boxing occurs?

Carlsbad answered 25/11, 2014 at 16:37 Comment(1)
C# Boxing DataTypes MSDN Boxing and UnBoxingGladsome
E
18

You've already got answers telling you that when ToString() is overridden for a value type, there will be no boxing when you call it, but it's nice to have some way of actually seeing that.

Take the type int? (Nullable<int>). This is a useful type because it is a value type, yet boxing may produce a null reference, and instance methods cannot be called through a null reference. It does have an overridden ToString() method. It does not have (and cannot have) an overridden GetType() method.

int? i = null;
var s = i.ToString(); // okay: initialises s to ""
var t = i.GetType(); // not okay: throws NullReferenceException

This shows that there is no boxing in the call i.ToString(), but there is boxing in the call i.GetType().

Eucken answered 25/11, 2014 at 16:49 Comment(0)
C
7

The other answers mention that the ToString call will not result in boxing. It's worth noting a corollary:

int i = 42;
String.Format("number: {0}", i.ToString());

will not result in boxing, whereas:

int i = 42;
String.Format("number: {0}", i);

will.

(You hear that, Resharper?)

(However, bear in mind that if you're applying a formatter to String.Format (e.g. CultureInfo, you need to use the second version)

Crackleware answered 12/10, 2015 at 18:55 Comment(0)
A
4

No, boxing does not occur. When virtual method is called, CLR looks for type object pointer to get actual overrriden method from method table. For value types there is no object pointer, so direct non-virtual call is made instead, JIT knows that there are no polimorphic side-effects because value types are sealed. However, boxing might occur if ToString() of value type calls base.ToString(): then actual instance is boxed and passed to System.ValueType.ToString()
Int32.ToString() does not call base.ToString() and use native implemenation, hence no boxing occur.

Aztec answered 25/11, 2014 at 16:58 Comment(0)
B
3

When you decompile the Int32.ToString() call you can see it implements FormatInt32 which is native C++ methods. The method is implemented as follows:

public override string ToString()
{
    return Number.FormatInt32(
    this,
    null,
    NumberFormatInfo.CurrentInfo);
}

[MethodImpl(MethodImplOptions.InternalCall)]
public static extern string FormatInt32(
    int value,
    string format,
    NumberFormatInfo info);

Which calls Int32ToDecChars:

wchar_t* COMNumber::Int32ToDecChars(
wchar_t* p,
unsigned int value,
int digits)
{
    LEAF_CONTRACT
    _ASSERTE(p != NULL);

    while (--digits >= 0 || value != 0) {
        *--p = value % 10 + '0';
        value /= 10;
    }
    return p;
}

It takes each digit, converts to a separate char and stores in a string. The string is then returned. So there is no boxing of int involved.

Under this link you can find fairly thorough explanation of what actually happens when invoking ToString() on an int. As a bonus the article also explains all the mechanisms behind Int32.Parse():

https://selvasamuel.wordpress.com/2008/03/14/boxingunboxing-in-net/

Brassy answered 25/11, 2014 at 16:50 Comment(3)
This doesn't show whether there's any boxing. All it shows is that if there is boxing, there is also later unboxing, but that isn't surprising.Eucken
The int is converted to char - another value type. And then string is constracted from char.Brassy
What I'm trying to say is this doesn't eliminate the possibility of it having been converted to object first, and back to int prior to that method being called.Eucken
L
2

Since ToString is overriden in Int32 class - no, there will no boxing in this case as no instance on object will be created.

Simply appropriate method of Int32 is called because of dynamic dispatch.

Leviticus answered 25/11, 2014 at 16:40 Comment(0)
B
-5

It depends on how the ToString() function implemented in Int32 class. Since the implementation done by .net framework, we can't confirm whether boxing happens or not.

Balduin answered 25/11, 2014 at 16:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.