Boxing questions relating to struct methods

T

Tom

Couple of questions relating to boxing. Firstly, I already know that boxing
is the processing of temporarily copying a ValueType (e.g. struct, enum) to
the heap so that the system can treat a value type like a reference type.
However, I have some questions relating to implicit boxing:

1. If I add custom instance method on a struct, will it box that type each
time the method is called? For example, suppose I have the following:

public struct MyStruct
{
private string _value;
public string Value
{
get {return _value;}
set {_value = value;}
}
public void DoInstanceStuff()
{
}
public static void DoStaticStuff()
{
}
}

MyStruct var;
var.DoInstanceStuff(); //<-- does this line box var?

2. Same question as #1 only relating to DoStaticStuff given that it is a
static method.

3. How do I substantiate the answer to either of the above questions?

4. If a value type is boxed, unboxed and then boxed again, does the system
reuse the original boxing's heap allocation or re-allocate a new area in the
heap. I'm presuming the later, but I wondered if the framework included
some sort of boxing optimization.

5. If I box a value type (explicit or implicit) and, while boxed, change one
of the value type's underlying field values (like through one of the value
type's methods), what does the system do?


Thanks,


Tom
 
J

Jon Skeet [C# MVP]

Tom said:
1. If I add custom instance method on a struct, will it box that type each
time the method is called? For example, suppose I have the following:

public struct MyStruct
{
private string _value;
public string Value
{
get {return _value;}
set {_value = value;}
}
public void DoInstanceStuff()
{
}
public static void DoStaticStuff()
{
}
}

MyStruct var;
var.DoInstanceStuff(); //<-- does this line box var?

No. The way to test this is to write a short test app and use ildasm to
see what the generated code does. If it doesn't contain an IL "box"
command, you're okay.
2. Same question as #1 only relating to DoStaticStuff given that it is a
static method.

No - it can't, as there might not *be* any instances to box.
3. How do I substantiate the answer to either of the above questions?

See above - and reading the specs, although they get somewhat tricky
sometimes about boxing.
4. If a value type is boxed, unboxed and then boxed again, does the system
reuse the original boxing's heap allocation or re-allocate a new area in the
heap. I'm presuming the later, but I wondered if the framework included
some sort of boxing optimization.

New allocation. To test:

MyStruct v = new MyStruct();
object o = v;
MyStruct u = (MyStruct)o;
object o2 = u;
Console.WriteLine (o==o2);

The above prints "False".
5. If I box a value type (explicit or implicit) and, while boxed, change one
of the value type's underlying field values (like through one of the value
type's methods), what does the system do?

The boxed value doesn't change. It is a box of the value at the time
that you perform the box - it's unrelated to the variable containing
the original value, so changing the variable to have a new value
doesn't change the boxed value.
 
T

Tom

Sweet. I was getting the feeling that no one has the cahones to answer my
question ;->. It sounds as if the only way that a value type can be boxed
is by passing it to a variable typed as a reference type (e.g. a variable
typed as object). Specifically, it sounds like there shouldn't be any
mysterious reasons why the system would box a value type without an obvious
reason. That's the answer I was looking for.


Thanks again,

Tom
 
J

Jon Skeet [C# MVP]

Tom said:
Sweet. I was getting the feeling that no one has the cahones to answer my
question ;->. It sounds as if the only way that a value type can be boxed
is by passing it to a variable typed as a reference type (e.g. a variable
typed as object). Specifically, it sounds like there shouldn't be any
mysterious reasons why the system would box a value type without an obvious
reason. That's the answer I was looking for.

It's not *quite* that simple. If you end up calling a method inherited
from Object or ValueType which isn't overridden, that will also end up
with a boxing operation, which is one reason to override ToString,
Equals, GetHashcode etc. Other than that though, the system certainly
tries to avoid boxing where it can.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top