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?
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.
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.
So just because a data class defines a toString doesn't mean you shouldn't override it.
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.
If
thisType
is a value type andthisType
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
, orEnum
and not overridden bythisType
. 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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With