Reputation: 8394
This question is more out of curiosity than a real problem. Consider the following code (C# 4.0, if it matters):
class Program {
static Point myPoint = new Point(3, 5);
static void Main(string[] args) {
Console.WriteLine("Point Struct Before: " + myPoint);
object point = GetPoint();
Console.WriteLine("Point Object Before: " + point);
myPoint.X = 10;
Console.WriteLine("Point Struct After: " + myPoint);
Console.WriteLine("Point Object After: " + point);
}
static object GetPoint() {
return myPoint;
}
}
This outputs the following:
Point Struct Before: 3;5
Point Object Before: 3;5
Point Struct After: 10;5
Point Object After: 3;5
Now, this works as it should, meaning the point returned by GetPoint()
is being copied rather than referenced. (Otherwise the last line would also have read "10;5".)
My question now is: Why does this work? How does the compiler know whether to copy or reference an object? Does this mean that this decision is done during runtime rather than during compilation?
Also, this now allows me to set point
to null
whereas struct
s can't be set to null
. Is the struct automatically converted into a nullable type?
Upvotes: 3
Views: 8785
Reputation: 8667
You are observing the process called boxing. It essentially converts a value type into a reference type.
Upvotes: 5
Reputation: 81151
Although Microsoft in some sense claims that all types derive from object, it's more helpful to regard value types as being things which are totally outside the type system, but which have boxed equivalents within the typing system (all of which derive from ValueType), along with widening conversion operators between them and the boxed equivalents. If one passes an a structure to a routine which expects an Object, one isn't really passing a value type, but rather the boxed equivalent of a value type. If that is passed around to other routines that expect Object, they will continue to use the same boxed object. If it is passed to routines that expect the structure, it will be converted back to a structure for use with those routines. Note that each time it's converted, a snapshot is taken of the value; changes to the snapshot will not affect the copied entity, nor vice versa.
Upvotes: 4
Reputation: 32750
Also, this now allows me to set point to null whereas structs can't be set to null. Is the struct automatically converted into a nullable type?
You are misunderstanding the whole process:
int i = 5;
object o = i; //Creates a new Int32 with value 5 and assigns it to the object'o' reference storing the value on the garbage collected heap. This is what is called boxing.
object o = null //Simply assigns 'null' to the object reference, it does nothing to the boxed value type 'o' was referencing before.
In the example above the boxed int
will eventually be collected by the GC from the garbage collected heap as no live reference is pointing at it anymore.
Upvotes: 9
Reputation: 9469
You are not converting myPoint
to an object, you are just creating a copy of the myPoint
structure (through the GetPoint
method) and assigning an object reference to it.
Upvotes: 4