Casting in VB.Net and C#

  • Thread starter Thread starter Ken Allen
  • Start date Start date
"One Handed Man [ OHM# ]"
OK, So now we have established that. I then put it to you that my
original statement is correct, which is that directCast only works
with reference types, because when they are Boxed, they become
referenced.

This is not completely right. You wrote:
"DirectCast can only be used on reference types"
A boxed integer is accessed using a reference to the heap, but an Integer
value is still not a reference type.

Your assertion was that Boxed types also work, this is
true.

BTW the assignment


Works during compile and runtime. The casting is done implicitly it
seems.

Enable option strict.
Thank you for your patience. I wont bother you further on this one as
we have done it to death.

You didn't bother me! :-)
 
Rob,
C# does indeed have pointers (check "unsafe" code), and VB can operate
similarly by using the Marshal class and pinned GC handles.
I was going to mention unsafe code, however I was gearing my answer to only
VB6 & VB.NET. I have not really used pinned GC handles, I'll have to
remember that hack (err trick) ;-). Remember with great power comes great
responsibility, using unsafe code & pinned GC handles significantly
increases your responsibility!
You can always use the binary serializer to serialize the entity to a byte
stream (and deserialize the byte stream back into the entity). Extremely
convenient, but it does add type information to the stream.
I did not mention the normal binary serializer directly as the OP wanted to
do a checksum, as you mention the type information will totally screw up the
checksum! ;-)

Thanks for the addition info.
In a type-safe OO system, you treat entities differently by using
polymorphism - which doesn't do EXACTLY the same thing under the hood, but
allows you to manipulate different entities with like interfaces in a
completely structured and type-safe manner.
This was part of the intent of my post, although you can cast the pointer in
C++ (or even use unsafe C# code) and do some truly "evil" (cool, neat,
clever) things, that .NET is a whole new ball game. The OP should consider
learning the new ways of doing things rather then continuing to rely on the
old way of doing things. Yes there may be performance issues (coping the
structure to calculate the checksum). However! is copying the structure the
performance issues you need to worry about in your app? You know the rule
where you optimize the code that has proven (via profiling) performance
issues, not the code you think has performance issues!

Although I do like the idea of a pinned pointer to calculate the checksum,
especially where that calculation is 200% encapsulated in its own class! My
concern would be where the layout of the structure (due to padding) is
slightly different then the layout of the structure on "paper" and disk. For
example reference types in the structure.

Just a thought
Jay
 
OK, one last thing.
A boxed integer is accessed using a reference to the heap, but an
Integer value is still not a reference type.

I know an integer is not a reference type, i didnt say it was. Maybe what I
should have said was that DirectCast cannot be given references to Value
Types ( Unboxed ) . As when they are boxed they become a class and to the
outside world become reference types in disguise.

QUOTES
For each value type, the runtime supplies a corresponding boxed type, which
is a 'class' that has the same state and behavior as the value type. Some
languages require you to use special syntax when the boxed type is required;
others automatically use the boxed type when it is needed. When you define a
value type, you are defining both the boxed and the unboxed type.
END QUOTES

BTW: I Cant beleive, I had option strict OFF, I turned it off to test
something the other day and forgot to switch it back on again :Grrrrrr ;-)

Regards - OHM


Armin said:
"One Handed Man [ OHM# ]"
OK, So now we have established that. I then put it to you that my
original statement is correct, which is that directCast only works
with reference types, because when they are Boxed, they become
referenced.

This is not completely right. You wrote:
"DirectCast can only be used on reference types"
A boxed integer is accessed using a reference to the heap, but an
Integer value is still not a reference type.

Your assertion was that Boxed types also work, this is
true.

BTW the assignment


Works during compile and runtime. The casting is done implicitly it
seems.

Enable option strict.
Thank you for your patience. I wont bother you further on this one as
we have done it to death.

You didn't bother me! :-)

Regards - OHM# (e-mail address removed)
 
A lurker would like to say "Thank You!" to Armin. What a great set of
references!

Armin Zingler said:
"One Handed Man [ OHM# ]"
What do you mean by boxed ?

A variable declared As Object occupies 4 bytes. If you assign a value type
to the variable, the size of the object can not always be 4 bytes to fit
into the variable. Consequently the object is stored on the heap and the
reference to the object is stored in the variable. Just like reference
types.


Look for "boxed" in
http://msdn.microsoft.com/library/en-us/cpguide/html/cpconvaluetypes.asp

See also KB article 311327:
http://support.microsoft.com/default.aspx?scid=kb;[LN];311327

and (look for "boxing"):
http://msdn.microsoft.com/library/en-us/dv_vstechart/html/vbtchmicrosoftvisualbasicnetinternals.asp




Strange, I didn't find anything in the VB.Net docs.... :-(


--
Armin

http://www.plig.net/nnq/nquote.html
http://www.netmeister.org/news/learn2quote.html
 
yes but he still didnt answer the last question.

OHM

A lurker would like to say "Thank You!" to Armin. What a great set of
references!

Armin Zingler said:
"One Handed Man [ OHM# ]"
What do you mean by boxed ?

A variable declared As Object occupies 4 bytes. If you assign a
value type to the variable, the size of the object can not always be
4 bytes to fit into the variable. Consequently the object is stored
on the heap and the reference to the object is stored in the
variable. Just like reference types.


Look for "boxed" in
http://msdn.microsoft.com/library/en-us/cpguide/html/cpconvaluetypes.asp

See also KB article 311327:
http://support.microsoft.com/default.aspx?scid=kb;[LN];311327

and (look for "boxing"):
http://msdn.microsoft.com/library/en-us/dv_vstechart/html/vbtchmicrosoftvisualbasicnetinternals.asp
Strange, I didn't find anything in the VB.Net docs.... :-(


--
Armin

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

Regards - OHM# (e-mail address removed)
 
"One Handed Man [ OHM# ]"
OK, one last thing.


I know an integer is not a reference type, i didnt say it was.

The decisive part is your statement that "..directcast only works with
reference types". As Directcast works with boxed Integers, you implicitly
say that an Integer is a reference types.

Maybe
what I should have said was that DirectCast cannot be given
references to Value Types ( Unboxed ) .
yes

As when they are boxed they
become a class and to the outside world become reference types in
disguise.

IMO: no. An object that is a value type, like a structure, can never become
a class.

Maybe you are looking for a not existing problem. :-)


Different example: You can pass a value type ByRef to a procedure. It will
also be accessed using the passed reference but the object is still not a
reference type.
 
Armin said:
IMO: no. An object that is a value type, like a structure, can never
become a class.


OHm Writes:
The following quote is from Microsoft Itself.

QUOTES
For each value type, the runtime supplies a corresponding boxed type, which
<<<<<<<<<<<<<<< THIS LINE
is a 'class' that has the same state and behavior as the value type. Some
<<<<<<<<<<<<<<< AND THIS LINE
languages require you to use special syntax when the boxed type is required;
others automatically use the boxed type when it is needed. When you define a
value type, you are defining both the boxed and the unboxed type.
END QUOTES


OHM
 
One Handed Man said:
OHm Writes:
The following quote is from Microsoft Itself.

QUOTES
For each value type, the runtime supplies a corresponding boxed type,
which <<<<<<<<<<<<<<< THIS LINE
is a 'class' that has the same state and behavior as the value type.
Some <<<<<<<<<<<<<<< AND THIS LINE
languages require you to use special syntax when the boxed type is
required; others automatically use the boxed type when it is needed.
When you define a value type, you are defining both the boxed and the
unboxed type. END QUOTES

Interesting. I think it is not completely true. Example:

Dim o As Object

o = Me 'In Form1
DirectCast(o, Form1).Visible = True

o = New Point(0, 0)
DirectCast(o, Point).X = 7

Last line fails.

Well, saying "it is not completely true".... Say, after applying
Directcast, it is not handled as a boxed value type anymore, so the
statement can also be considered true. That's a matter of interpretation. In
the end, everything is data or code. ;-) A test comes into my mind:

test(DirectCast(o, Point))

Private Sub test(ByRef p As Point)

End Sub

Question: Which reference is passed to sub test? The reference to the heap,
or is the point copied to the stack and a reference to the copy on the stack
is passed? Result: the latter is the case. If it were handled as a reference
type, the former would apply.
 
Honest answer, I dont know !

Maybe you could start a new thread and ask, Jay to give his comment on this
, I find it both intruiging and perplexing. I dont like things I cant get to
the bottom of.

Regards - OHM


Armin said:
Interesting. I think it is not completely true. Example:

Dim o As Object

o = Me 'In Form1
DirectCast(o, Form1).Visible = True

o = New Point(0, 0)
DirectCast(o, Point).X = 7

Last line fails.

Well, saying "it is not completely true".... Say, after applying
Directcast, it is not handled as a boxed value type anymore, so the
statement can also be considered true. That's a matter of
interpretation. In the end, everything is data or code. ;-) A test
comes into my mind:

test(DirectCast(o, Point))

Private Sub test(ByRef p As Point)

End Sub

Question: Which reference is passed to sub test? The reference to the
heap, or is the point copied to the stack and a reference to the copy
on the stack is passed? Result: the latter is the case. If it were
handled as a reference type, the former would apply.

Regards - OHM# OneHandedMan{at}BTInternet{dot}com
 
One Handed Man said:
Honest answer, I dont know !

What are you referring to?
Maybe you could start a new thread and ask, Jay to give his comment
on this , I find it both intruiging and perplexing. I dont like
things I cant get to the bottom of.

Sorry, what does "intruiging" mean?
 
Armin,
test(DirectCast(o, Point))

Private Sub test(ByRef p As Point)

End Sub

Question: Which reference is passed to sub test? The reference to the heap,
or is the point copied to the stack and a reference to the copy on the stack
is passed? Result: the latter is the case. If it were handled as a reference
type, the former would apply.
A reference to a copy on the stack is passed, as the DirectCast unboxed the
Point object. One way to see what is happening is to use ILDASM.EXE to see
what IL was created.
o = New Point(0, 0)
DirectCast(o, Point).X = 7
Remember when you box or unbox a value type a copy of the data is made! The
DirectCast does an unbox on the o variable. The assignment to o made a copy
of the value type when it boxed it, then the DirectCast made a second copy
when it unboxed the value type.

Which is where the error that VB.NET gives you is nice, as it prevents you
from having an extremely obscure bug in your application! ;-)

Box uses the "special class" that OHM referenced and copies the data to it,
while unbox copies the data from the "special class".

I'm not sure if the "Common Language Infrastructure Standard" will explain
it any better as it states it in a similar manner to OHM's quote. See
"\Program Files\Microsoft Visual Studio .NET 2003\SDK\v1.1\Tool Developers
Guide\docs\Partition I Architecture.doc" if you have VS.NET 2003 installed,
for VS.NET 2002 it should be in a similar "2002" path.

I have not followed this thread closely, however I get the impression you
are both correct, you are just describing a different angle of the same
beast. ;-)

Hope this helps
Jay
 
Hi Armin,

Intriguing, why OHM gets a "what does intruiging" means back, and I always
"I don't understand Sorry" and can I try to find what part you do not
understand the syntax or the meaning.

:-))

Cor
 
Jay B. Harlow said:
Armin,

A reference to a copy on the stack is passed, as the DirectCast
unboxed the Point object. One way to see what is happening is to use
ILDASM.EXE to see what IL was created.
Remember when you box or unbox a value type a copy of the data is
made! The DirectCast does an unbox on the o variable. The assignment
to o made a copy of the value type when it boxed it, then the
DirectCast made a second copy when it unboxed the value type.

Right. That's what I wrote in the text you quoted.

I have not followed this thread closely, however I get the impression
you are both correct, you are just describing a different angle of
the same beast. ;-)

ACK. That's why I wrote "That's a matter of interpretation". ;)
 
What are you referring to?
Well, saying "it is not completely true".... Say, after applying
Directcast, it is not handled as a boxed value type anymore, so the
statement can also be considered true. That's a matter of interpretation. In
the end, everything is data or code. A test comes into my mind:

test(DirectCast(o, Point))

Private Sub test(ByRef p As Point)

End Sub

Question: Which reference is passed to sub test? The reference to the heap,
or is the point copied to the stack and a reference to the copy on the stack
is passed? Result: the latter is the case. If it were handled as a reference
type, the former would apply.

To me this would be the former. Point is a reference Type and the object
passed to DirectCast must be of the same type at runtime.




Sorry, what does "intruiging" mean?
Very interesting, something which captivates ones attention.



Regards - OHM# OneHandedMan{at}BTInternet{dot}com
 
Jay,
Thanks for stepping in to what has become a very confusing thread
for me at least. I think I now understand what's going on between all the
conversations between myself and Armin and what you have written here.

It all started when I replied to the OP stating that DirectCast only works
with reference type. Armin replied this was not the case IE Boxed/Unboxed.
When I looked into this I concluded that although this was true, that they
were in effect refrence types because of the way the CLR handles them at
runtime.

This was the essence of the disagreement.

I think that MS should really clear this up. I realise that this is unlikely
to cause anyone a significant problem however, from an academic point of
view it would be nice for MS to clearly state how this all works under the
covers.


Regards - OHM
 
Cor said:
Intriguing, why OHM gets a "what does intruiging" means back, and I
always "I don't understand Sorry" and can I try to find what part you
do not understand the syntax or the meaning.

:-))

???
Cor, I don't understand you (again).
 
Armin,
ACK. That's why I wrote "That's a matter of interpretation". ;)
I guess I would use perspective instead of interpretation.

Of course applying either "perspective" or "interpretation" is a matter of
interpretation also! ;-)

As we enter an endless recursive spiral of semantics ;-)

Jay
 
One Handed Man said:
I think that MS should really clear this up. I realise that this is
unlikely to cause anyone a significant problem however, from an
academic point of view it would be nice for MS to clearly state how
this all works under the covers.

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.
 
Back
Top