Armin,
If boxed value types are the same as reference types,
'o2 = o1' would also copy the reference - the reference to the object on
the heap. It doesn't.
From the point of view of the Framework (the CLR) "boxed value types" are
reference types. Period! The CLR documentation I gave states so. Period!
No amount of what you think you are seeing is going to change the fact that
"boxed value types" are "Reference types"! As you are seeing the "smoke and
mirrors" of VB.NET. ;-)
This is from the "Common Language Infrastructure" (CLI) which is the
definition of how the CLR itself works. (url previously given).
<quote>
7.2.4 Boxing and Unboxing of Values
For every Value Type, the CTS defines a corresponding Reference Type called
the boxed type. The reverse is not true: Reference Types do not in general
have a corresponding Value Type. The representation of a value of a boxed
type (a boxed value) is a location where a value of the Value Type may be
stored. A boxed type is an object type and a boxed value is an object.
All Value Types have an operation called box. Boxing a value of any Value
Type produces its boxed value, i.e. a value of the corresponding boxed type
containing a bit copy of the original value. All boxed types have an
operation called unbox. Unboxing results in a managed pointer to the bit
representation of the value.
Notice that interfaces and inheritance are defined only on Reference types.
Thus, while a Value Type definition (see clause
7.9.7_cor_Value_Type_Definitions) can specify both interfaces that shall be
implemented by the Value Type and the class (System.ValueType or
System.Enum) from which it inherits, these apply only to boxed values.
types. Further more, the type of the object stays the same when boxed,
doesn't it? The type is still System.Drawing.Point. System.Drawing.Point is
a value type, no matter if a certain Point object is boxed or not. The type
System.Drawing.Point is defined in the Framework, and I don't think the
Framework changes just because we execute a statement at run-time that boxes
an instance of the type.
No, according to the "Common Language Infrastructure" a "boxed type" is
created, I suspect by the JIT, as I have not read that far into the CLI yet.
The way I think of this is the "boxed ValueType" type is a proxy for the
respective "ValueType" type, allowing the "boxed ValueType" to be a
reference type that exists on the heap, while the "ValueType" itself exists
on the stack. That both "boxed ValueType" & "ValueType" are treated
identical at the IL & higher level (in that you never actually see the
"boxed ValueType" type). My understanding is the "boxed ValueType" type is
at a level within the CLR itself (below the IL level).
Of course, at a lower level, both "types of types" are on the heap and there
is a reference to the objects in both cases.
Correct, that is why a "boxed value type" is a "reference type"!
< But: the term "reference type"
is not related to this low level. The term "reference type" is used at a
higher level at which we do distinguish between value types and reference
types.
Wrong: Reference Type & Value type is used at the lower level (IL, CLI)
also, just like we use them at the higher level, same meanings & rules!
If boxed value types are the same as reference types,
'o2 = o1' would also copy the reference - the reference to the object on
the heap. It doesn't.
The problem you are seeing is that "o2 = o1" does not do a simple
assignment! The VB.NET assignment operator (for objects) actually calls the
System.Runtime.CompilerServices.RuntimeHelpers.GetObjectValue(object) helper
function on the source (o1), the value returned is then assigned to your
destination (o2). This allows VB.NET to reinforce value semantics even with
"boxed value types". You can verify this using ILDASM.EXE.
According to MSDN: RuntimeHelpers.GetObjectValue: "Returns a boxed copy of
obj if it is a value class; otherwise obj itself is returned". Hence GetObje
ctValue
enforces value semantics.
Unfortunately due to the "extra code" (the GetObjectValue) injected by
VB.NET, I don't see a way to "show the code" to show you that a "boxed value
type" is a reference type. If you know C#, it does not call the
GetObjectValue...
I will agree with you that VB.NET makes "boxed value types" appear to be
something more special then they really are. In that GetObjectValue causes a
copy to be made. However! I hope you will agree that just because they
appear not to be a reference type, does not make them not a reference type!
Hope this helps
Jay