Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

boxing on structs when calling ToString()

Tags:

performance

c#

I've often wondered if the following scenario actually happens in c#

If I have a struct but I don't explicitly override any of the methods that derived from object such as ToString(), GetHashCode(), etc then if I declare a local instance of my struct class and call 'ToString()' on it, would my struct get boxed i.e would the CLR convert it implicitly to an object on the heap and then call ToString()? Or is it clever enough to know that there's no implementation for that struct and ignore it?

i.e

public struct Vector2D
{
    public float m_x;
    public float m_y;


    ...... etc
}


void SomeFunc()
{
  Vector2D aVec = new Vector2D();
  Console.WriteLine(aVec.ToString()); // <-- does aVec get boxed here?
  ..... 
}

== Edit - Update== Mehrdad's link to MSDN, whilst being useful has confused me slighly. I'll quote and see if any one can unpick this for me

When a callvirt method instruction has been prefixed by constrained thisType, the instruction is executed as follows:

If thisType is a reference type (as opposed to a value type) then ptr is dereferenced and passed as the 'this' pointer to the callvirt of method.

If thisType is a value type and thisType implements method then ptr is passed unmodified as the 'this' pointer to a call method instruction, for the implementation of method by thisType.

If thisType is a value type and thisType does not implement method then ptr is dereferenced, boxed, and passed as the 'this' pointer to the callvirt method instruction.

So does that mean that if I don't explicitly implement ToString() on my struct type that it will fall into the last case and get boxed? Or am I mis-understanding it somewhere?

like image 542
zebrabox Avatar asked Aug 08 '09 14:08

zebrabox


People also ask

What happens if you call toString on a string?

ToString is a method defined in the Object class, which is then inherited in every class in the entire framework. The ToString method in the String class has been overwritten with an implementation that simply returns itself. So there is no overhead in calling ToString() on a String-object.

Why is toString not working?

Your Node class does not override the toString() method and falls back to use the Object. toString() method instead. Also I think it is a bit confusing that you add a value but return a Node instead of a value with get(). Update: to print the value of your Node add the following code to your Node class.

Is toString always override?

So just because a data class defines a toString doesn't mean you shouldn't override it.

Can you override toString?

We can override the toString() method in our class to print proper output. For example, in the following code toString() is overridden to print the “Real + i Imag” form.


1 Answers

If thisType is a value type and thisType does not implement method then ptr is dereferenced, boxed, and passed as the 'this' pointer to the callvirt method instruction.

This last case can occur only when method was defined on Object, ValueType, or Enum and not overridden by thisType. In this case, the boxing causes a copy of the original object to be made.

The answer is yes, the value type is boxed. This is why it is always a good thing to override ToString() on custom structs.

like image 165
Kenan E. K. Avatar answered Sep 29 '22 03:09

Kenan E. K.