Casting in VB.Net and C#

C

Cor

Hi Jay,

I followed this thread and did not understand well what it was all about.

Has it to do with the old problem that a reference to a value cost more
memory and processing than a copy of a value?

Cor
 
O

One Handed Man [ OHM# ]

Just when I thought it was safe to go into the kicthen . . . . .

In my mind, once it has become boxed. As far as the CLR is concerned, it
seems that it might be handled as a reference type in a special way.

I'm glad you dont find a problem with it, that means you can sleep easy at
night, us mere mortals sometimes find it difficult when our IQ's are less
than 240.

;-)


Maybe it's time to end the thread ?

Regards - OHM



Armin said:
What has to be clarified? There are reference types, there are value
types, and there are boxed value types. I don't find the problem.

Regards - OHM# OneHandedMan{at}BTInternet{dot}com
 
J

Jay B. Harlow [MVP - Outlook]

Cor,
Has it to do with the old problem that a reference to a value cost more
memory and processing than a copy of a value?
I'm not sure how you mean 'reference', do you mean reference parameters or
reference types?

You are correct using boxed value types will cost more memory & processing
time, as the values need to be boxed & unboxed (placed on the heap & removed
from the heap).

This thread is primarily about when a value type becomes a "reference type"
which occurs when you assign a value type to an object variable. Within the
CLR this is the box IL instruction. Its also about what's the best way to
refer to this "boxed value type". I use both "boxed value type" and
"reference type", as I consider a "boxed value type" is a "reference
type"...

Hope this helps
Jay
 
J

Jay B. Harlow [MVP - Outlook]

OHM & Armin:
In my mind, once it has become boxed. As far as the CLR is concerned, it
seems that it might be handled as a reference type in a special way.
Correct! Once a value type is boxed, it is treated as any other reference
type! (I'm sure there are one or two special rules, however I have not come
across them yet).

See "7.2.4 - Boxing and Unboxing of Values" in
"\Program Files\Microsoft Visual Studio .NET 2003\SDK\v1.1\Tool Developers
Guide\docs\Partition I Architecture.doc" (or the respective SDK or VS.NET
2002 locations).

The CLR needs to box a value type any time that value type needs to be
"treated" as a Reference type, which includes (note there may be other
places that cause boxing to occur):
- Assigning a value type to an Object variable
- Assigning any enum to a System.Enum variable
- Assigning any value type to a System.ValueType variable
- Assigning a value type to any Interface variable
- Using overridable methods inherited from Object, that are not overridden
in a Structure (ToString for example)

The CLR needs to unbox a "boxed value type" then it assigns(casts) one of
above variables to a variable of the respective value type.

Remember that IL has special instructions (box & unbox), so the CLR itself
knows how to convert the value type on the stack into a reference type on
the heap (boxing) and converting a boxed value type on heap to a value type
on the stack (unboxing). VB.NET chose to support the IL box and unbox
instructions implicitly in some cases (boxing mostly) and via the CType &
DirectCast instructions (unboxing mostly, you can use CType to box). C# uses
a normal cast instruction. conceptually someone designing their own language
could introduce some distinctive keywords that represents boxing & unboxing,
however I am not aware of any that specifically have.

Most of the above is what you two have already stated, in one form or
another!

Of course I may have just tipped the canoe again, and every one is back in
the water ;-)

Hope this helps
Jay
 
A

Armin Zingler

You 'tipped the canoe' ;-)
I use both "boxed value type" and
"reference type", as I consider a "boxed value type" is a
"reference type"...


It is not as my previous example showed. See another one:

Dim f1, f2 As Form1
Dim o1, o2 As Object

f1 = New Form1
f2 = f1
o1 = New Point(10, 20)
o2 = o1

'f2 = f1' copies the reference because a Form is a class and a class is a
reference type. 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 object is copied => boxed value types are not
reference types.

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. 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. 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.
 
J

Jay B. Harlow [MVP - Outlook]

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
 
A

Armin Zingler

Jay,

this is actually the reply to your other message (11:43 your local time
(18:43 my local time *g*)), but I could not send it:

("Posting failed, Server result: 441 (629) Article Rejected -- Ill-formed
message id '<[email protected]' in field 'References:'")


Anyway, here it is:


I read it, I wrote something - but here is the short version of the answer:
;-)

You say that you don't know whether System.Drawing.Point is a reference type
or a value type?
 
J

Jay B. Harlow [MVP - Outlook]

Armin,
You say that you don't know whether System.Drawing.Point is a reference type
or a value type?
No, I did not say that.

What I said was that System.Drawing.Point is a value type, that under the
covers the CLR also has a System.Drawing.Point 'reference type' that it uses
when you box a System.Drawing.Point value.

As a "boxed value type" is a "reference type".
("Posting failed, Server result: 441 (629) Article Rejected -- Ill-formed
message id '<[email protected]' in field
'References:'")
I understand that this is caused by the "References" field in the header to
be too long. I attempted to correct the references.

Hope this helps
Jay
 
A

Armin Zingler

Jay B. Harlow said:
Armin,
No, I did not say that.

By saying it depends on whether a point *object* is boxed or not, you
implicitly say that it does not depend on the *type* itself but on the
*instance*. In other words: According to the type you can not say whether
the type is a reference type or a value type.
What I said was that System.Drawing.Point is a value type, that under
the covers the CLR also has a System.Drawing.Point 'reference type'
that it uses when you box a System.Drawing.Point value.

dim o as object = new point (0,0)
msgbox o.gettype.fullname

=> Still "System.Drawing.Point"

Hmm....

;-)
 
J

Jay B. Harlow [MVP - Outlook]

Armin,
Forgive my bluntness: Are you intentionally trying to turn things around or
do you truly not get what I am trying to explain?
By saying it depends on whether a point *object* is boxed or not, you
implicitly say that it does not depend on the *type* itself but on the
*instance*. In other words: According to the type you can not say whether
the type is a reference type or a value type.
There are clearly documented ways on how to tell if a type is a reference
type or a value type. Which I know you understand.

Just as its documented when a value type can "also be" a reference type.
Which I get the impression eludes you, and my explanations are not helping
:-(
Hmm....

;-)
I get the impression you are simply trying to turn things around, without no
real desire to fully understand what I am tying to explain to you.

So I will conclude that this discussion has passed its useful life span...

Jay
 
A

Armin Zingler

Jay B. Harlow said:
Armin,
Forgive my bluntness: Are you intentionally trying to turn things
around or do you truly not get what I am trying to explain?

I could ask you the same. Please stay objective and don't get personal or
provocative.
There are clearly documented ways on how to tell if a type is a
reference type or a value type. Which I know you understand.


There are clear proofes that back up my statements, but obviously you are
ingoring all of them. I would not have a problem to confess if I was wrong.
Please don't get me wrong, I just want to help you and make it easier for
you to agree with me even if it seems this is a one-way. I am really not
resentful.
Just as its documented when a value type can "also be" a reference
type. Which I get the impression eludes you, and my explanations are
not helping :-(

Sorry, but you still didn't get the point. I'll try to ask again:

1. Do you consider System.Drawing.Point to be a value type or a reference
type? You ignored this question.


2. You also ignored:

<quote>
dim o as object = new point (0,0)
msgbox o.gettype.fullname

=> Still "System.Drawing.Point"
</quote>

Could you please tell me the full qualified name of a boxed
System.Drawing.Point object?


3. One more proof (refering to "...clearly documented ways on how to tell if
a type is a reference type or a value type"):

dim o as object = new point(0,0)
if typeof o is valuetype then
msgbox "valuetype"
end if

Despite the point object is boxed, the msgbox shows. Conclusion: a boxed
point object is a valuetype. BTW, the object is *not* unboxed before type
comparison takes place. If this still does not convince you I won't find
more words.
 
J

Jay B. Harlow [MVP - Outlook]

Armin,
1. Do you consider System.Drawing.Point to be a value type or a reference
type? You ignored this question.
System.Drawing.Point is a value type, as it inherits from System.ValueType!
When System.Drawing.Point is boxed it is also a reference type, as defined
by the CLI.
Could you please tell me the full qualified name of a boxed
System.Drawing.Point object?
System.Drawing.Point

Yes, the value type itself & the "boxed value type" both have the exact same
type name! In fact both will return the exact same System.Type object when
you use the Object.GetType method. The CLR itself is hiding the fact there
is a boxed type is involved. If you need specifics on this hiding you will
need to read the Common Language Infrastructure specification, previously
quoted and referenced.
3. One more proof (refering to "...clearly documented ways on how to tell if
a type is a reference type or a value type"):
dim o as object = new point(0,0)
if typeof o is valuetype then
I would expect "typeof o is valuetype" to be true as System.Drawing.Point is
a value type (as it inherits from System.ValueType). Remember that
System.ValueType itself is actually a Reference Type, based on CLI reference
I gave earlier (and the MSDN topic on System.ValueType).

This is where IMHO you are missing the point, and I am having a HELL of a
time explaining it to you! I actually thought you had it earlier... Point is
a value type, when it is boxed it is a reference type. This is defined by
the CLR itself. The "type" of the box itself (as defined by GetType &
TypeOf) is the value type, so comparing the type of the boxed value is going
to be the value type itself. The CLR does this to simplify your code. If the
CLR did not do this, you would need to know what the name of a boxed Point
was, which means the 'boxed value type' type would need to be known at
compile time. Reading the passage I gave earlier from the CLI, I get the
impression the boxed value type's type is not created until runtime, this
makes sense to me as its not needed until runtime. The designers of the CLR
decided to make every ones lives easier by having the boxed value type
return the same type as the value type itself. For example, I only need to
know Point in the code below, I don't need to know what the 'boxed Point'
type is.

If TypeOf o Is Point Then
Dim pt As Point = DirectCast(o, Point)
End If
There are clear proofes that back up my statements, but obviously you are
ingoring all of them. I would not have a problem to confess if I was
wrong.
I have not (knowingly) ignored any of your "proofs" I made a sincere effort
to demostrate where each of your "proofs" are not really proving anything. I
get the impression I did not do a very good job, hence my frustration with
myself. Both the CLR & VB.NET are going out of their way to make a boxed
value type appear to be a normal value type. Hence your "proofs", show you
exactly what you are expecting. When I look at your proofs, I see exactly
what you think you are seeing. Reading the CLI and looking at the IL I
understand why you think they are proofing, what you think they are
proofing, however I look a little deeper, yes as a child I disassembled most
of my toys. Looking at the underlying IL I see how VB.NET is hiding the
reference type from you with the GetObjectValue call. Also reading the CLI
specification I see how the CLR makes a reference type for the value type
under the covers and maps this two types to the same type to simplify our
code. Hence there is no need for ValueType & "Boxed ValueType" types in our
source! Such as those found in Java. For example: Java's int is a value
type, while its Integer is a class in the Java class library that represents
a boxed int. By making "boxed value types" reference types, the .NET
designers avoid requiring .NET developers needing to define the equivalent
Java's Integer class, as the CLR takes care of it for you, transparently!

Hope this helps
Jay
 
A

Armin Zingler

Jay B. Harlow said:
Armin,
1. Do you consider System.Drawing.Point to be a value type or a
reference type? You ignored this question.
System.Drawing.Point is a value type, as it inherits from
System.ValueType! When System.Drawing.Point is boxed it is also a
reference type, as defined by the CLI.
Could you please tell me the full qualified name of a boxed
System.Drawing.Point object?
System.Drawing.Point

Yes, the value type itself & the "boxed value type" both have the
exact same type name! In fact both will return the exact same
System.Type object when you use the Object.GetType method. The CLR
itself is hiding the fact there is a boxed type is involved. If you
need specifics on this hiding you will need to read the Common
Language Infrastructure specification, previously quoted and
referenced.
[...I-also-read-the-rest-only-did-not-quote-it...]

I did not read the whole CLS so far. ;-) I don't wanna get megalomaniac ;)
but is it possible that the CLS documentation may "throw everything in one
pot" (=lumps everything together) concerning this specific point? Maybe
instead of writing "boxed value types are handled equally to reference
types" they write "boxed value types are reference types"? That's what I am
really not completely sure about it. Maybe I'll get into this level one day.
I'm not fit to discuss about it, yet.

My doubts come from the fact that in the managed world there *must* be
metadata that describes all types, but now suddenly there are "on the fly"
types that are not defined anywhere. That's where the contradiction comes
from IMO.

I can not imagine that we always strictly distinguish between reference
types and value types at a "high" level, e.g. when talking about it in this
group, whereas it is actually a CLI level issue. Therefore I thought (and,
sorry, I still think (probably *because* I'm not a low-level guy yet)) the
terms are not related to the CLI level. In addition, as you/the CLS says
that all value types are reference types because System.ValueType is a class
(I did know this), I do not understand why we always say that a type is
_either_ a reference type _or_ a value type. Following your explanations,
any type is a reference type (because System.Valuetype is a class), but not
any reference type is also a value type. That's completely new to me, and
that's where and why we still disagree.

So let's say: EOT (the last time...). I'm really interested in which
insights will happen to me the next months. *g* I did not want to say that I
am absolutely right, I just wanted to put my statements opposite to yours to
find out the core that reveal the cause for our different points of view.
 
A

Armin Zingler

Armin Zingler said:
find out the core that reveal the cause for our different points of view.

What??

....find out the cause for our different points of view.
 
J

Jay B. Harlow [MVP - Outlook]

Armin,
but is it possible that the CLS documentation may "throw everything in one
pot" (=lumps everything together) concerning this specific point?
Possible, but I don't think that is the reason. However I'm not sure either
way.
Maybe
instead of writing "boxed value types are handled equally to reference
types" they write "boxed value types are reference types"?
Unfortunately depending on your point of view that quickly decades into
subtle semantic issues.

They wrote "boxed value types are reference types", I understand the why
they are reference types, I am willing to live with it.
My doubts come from the fact that in the managed world there *must* be
metadata that describes all types, but now suddenly there are "on the fly"
types that are not defined anywhere. That's where the contradiction comes
from IMO.
I can see where that would cause confusion, unfortunately it may get worst
when we start learning how the meta data for Generics in Whidbey is stored,
based on my understanding on what I have read so far.

Hope this helps
Jay

Armin Zingler said:
Jay B. Harlow said:
Armin,
1. Do you consider System.Drawing.Point to be a value type or a
reference type? You ignored this question.
System.Drawing.Point is a value type, as it inherits from
System.ValueType! When System.Drawing.Point is boxed it is also a
reference type, as defined by the CLI.
Could you please tell me the full qualified name of a boxed
System.Drawing.Point object?
System.Drawing.Point

Yes, the value type itself & the "boxed value type" both have the
exact same type name! In fact both will return the exact same
System.Type object when you use the Object.GetType method. The CLR
itself is hiding the fact there is a boxed type is involved. If you
need specifics on this hiding you will need to read the Common
Language Infrastructure specification, previously quoted and
referenced.
[...I-also-read-the-rest-only-did-not-quote-it...]

I did not read the whole CLS so far. ;-) I don't wanna get megalomaniac ;)
but is it possible that the CLS documentation may "throw everything in one
pot" (=lumps everything together) concerning this specific point? Maybe
instead of writing "boxed value types are handled equally to reference
types" they write "boxed value types are reference types"? That's what I am
really not completely sure about it. Maybe I'll get into this level one day.
I'm not fit to discuss about it, yet.

My doubts come from the fact that in the managed world there *must* be
metadata that describes all types, but now suddenly there are "on the fly"
types that are not defined anywhere. That's where the contradiction comes
from IMO.

I can not imagine that we always strictly distinguish between reference
types and value types at a "high" level, e.g. when talking about it in this
group, whereas it is actually a CLI level issue. Therefore I thought (and,
sorry, I still think (probably *because* I'm not a low-level guy yet)) the
terms are not related to the CLI level. In addition, as you/the CLS says
that all value types are reference types because System.ValueType is a class
(I did know this), I do not understand why we always say that a type is
_either_ a reference type _or_ a value type. Following your explanations,
any type is a reference type (because System.Valuetype is a class), but not
any reference type is also a value type. That's completely new to me, and
that's where and why we still disagree.

So let's say: EOT (the last time...). I'm really interested in which
insights will happen to me the next months. *g* I did not want to say that I
am absolutely right, I just wanted to put my statements opposite to yours to
find out the core that reveal the cause for our different points of view.


--
Armin

http://www.plig.net/nnq/nquote.html
http://www.netmeister.org/news/learn2quote.html
 
J

jerry

Your posts are the _only_ reason I even open this newsgroup. And I am sure
this is true of others. Please do not let these people get to you. Please
just drop their antagonistic threads. Have you not noticed how many people
cease to post in this group forever because of Armin and Herfried
snottiness. They seem determined to lord this newsgroup and will turn on
any other person who dares to post regularly. I, for one, do not want to
see you go. So, please, drop it, move on, do not respond to their posts.

From a lurker who is really, really sick of this newsgroup.
 
J

Jay B. Harlow [MVP - Outlook]

Jerry,
Thank you for the support!

I do not really view Armin as antagonistic. Although we all (me included)
have our antagonistic days.

I find both Armin & Herfried to be very good contributors to this newsgroup!
I even learn new things from them on occasion. (although I may not
necessarily acknowledge on each instance).

Don't worry I'm not going anywhere any time soon. As I've stated in other
posts, I find the newsgroups a good place to learn more myself. As when I
decide to answer difficult subtle questions, such as the discussion Armin &
I are having in this thread, it makes me think more and research more.
Hopefully both Armin & I walk out of this discussion with a better
understanding of how & why of the framework...

Thanks again for the words
Jay
 

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