Converting between Object and Classes that inherit object

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

Hi guys,
First off i'm using VB with VS2005 Beta2

I'm looking to make a Collection of a class I am going to call DisplayObject.
This class will have a few properties that i can call.. (These will include
Name and Value amongst other things)

I want to make a Collection of DisplayObjects which should (will) only
contain display objects.

The problem is when i retrieve one from that collection I get an Object when
I want a DisplayObject. Is there a way I can convert that object to a
DisplayObject?

When I try an implicit conversion i.e.
Dim myDisplayObject as DisplayObject = myCollection.Item(index)
but this gives me a warning when i try to build and I get a 'Build Failed'
status

Any ideas?
 
Use CType :-
Dim myDisplayObject as DisplayObject = CType(myCollection.Item(index),
DisplayObject)

Peter
 
....also note that if you don't need a conversion and a cast will do, then
DirectCast is infinitely faster...
Dim myDisplayObject as DisplayObject=DirectCast(myCollection.Item(index),
DisplayObject)


Cheers
Daniel
 
Thanks for that... sounds like my reference and value types are getting
mangled... my rule is still the same however: Never use CType over
DirectCast unless you really need to <g>

Look at these two in ildasm to see where I was coming form...

Dim ar As New ArrayList()
Public Sub MyMethod()
Dim o As Int32 = CType(ar.Item(0), Int32)
End Sub

Public Sub MyMethod2()
Dim o As Int32 = DirectCast(ar.Item(0), Int32)
End Sub

The outcome of some measurements I did a while back when converting/casting
a double in VB, are in the comments section here:
http://blogs.msdn.com/bclteam/archive/2005/02/11/371436.aspx

Cheers
Daniel
 
Ok, I see where you are coming from. Now here is what really puzzles me. The
basic types (Int32, Double etc) are hadled by the VB Compiler support
classes and thus the picture is somewhat mudded. Try replacing the Int32
with Rectangle (value type). We get the following for CType:

IL_0008: callvirt instance object
[mscorlib]System.Collections.ArrayList::get_Item(int32)
IL_000d: dup
IL_000e: brtrue.s IL_0020
IL_0010: pop
IL_0011: ldtoken [System.Drawing]System.Drawing.Rectangle
IL_0016: call class [mscorlib]System.Type
[mscorlib]System.Type::GetTypeFromHandle(valuetype
[mscorlib]System.RuntimeTypeHandle)
IL_001b: call object
[mscorlib]System.Activator::CreateInstance(class [mscorlib]System.Type)
IL_0020: unbox [System.Drawing]System.Drawing.Rectangle
IL_0025: ldobj [System.Drawing]System.Drawing.Rectangle
IL_002a: stloc.0

For DirectCast we get

IL_0008: callvirt instance object
[mscorlib]System.Collections.ArrayList::get_Item(int32)
IL_000d: unbox [System.Drawing]System.Drawing.Rectangle
IL_0012: ldobj [System.Drawing]System.Drawing.Rectangle
IL_0017: stloc.0

Looks much simpler except the lines IL_0011 through IL_001b are only
executed if the array element is NULL. Since using DirectCast you need to
check for NULL anyway, there is absolutely no difference.

The surprising thing is that CType(xxx, Int32) or to any other simple type,
results in a rather complex call to
Microsoft.VisualBasic.CompilerServices.XXConverter, that tries to cast to
IConvertible and perform the conversion, rather than a cast. Not exactly
surprising, since CType is supposed to mimic VB6 CType, i.e. convert a value
by any means possible short of starting WWIII, but somewhat disappointing
 
I see what you mean about user defined valuetypes versus intrinsic value
types (and let's not forget enums), good catch... Not sure about the
"absolutely no difference" bit (in most/some cases we don't check for null
since the context of the code can assert the reference is really pointing to
something), but even then we are really splitting hairs so I agree...

Overall my sentiments exactly... You hit it on the head with "Not surprising
but rather disappointing"... it sums up my feelings about the VB compiler
overall.

A few more examples of the dirtiness of the VB compiler:
http://www.danielmoth.com/Blog/2005/05/explicit-assignment-slower.html
http://groups.google.com/group/micr...read/thread/61cc840f4e57a84b/98a3af33b2591451
http://blogs.gotdotnet.com/cambecc/categoryview.aspx/VB Performance

Cheers
Daniel
--
http://www.danielmoth.com/Blog/

Alex Feinman said:
Ok, I see where you are coming from. Now here is what really puzzles me.
The basic types (Int32, Double etc) are hadled by the VB Compiler support
classes and thus the picture is somewhat mudded. Try replacing the Int32
with Rectangle (value type). We get the following for CType:

IL_0008: callvirt instance object
[mscorlib]System.Collections.ArrayList::get_Item(int32)
IL_000d: dup
IL_000e: brtrue.s IL_0020
IL_0010: pop
IL_0011: ldtoken [System.Drawing]System.Drawing.Rectangle
IL_0016: call class [mscorlib]System.Type
[mscorlib]System.Type::GetTypeFromHandle(valuetype
[mscorlib]System.RuntimeTypeHandle)
IL_001b: call object
[mscorlib]System.Activator::CreateInstance(class [mscorlib]System.Type)
IL_0020: unbox [System.Drawing]System.Drawing.Rectangle
IL_0025: ldobj [System.Drawing]System.Drawing.Rectangle
IL_002a: stloc.0

For DirectCast we get

IL_0008: callvirt instance object
[mscorlib]System.Collections.ArrayList::get_Item(int32)
IL_000d: unbox [System.Drawing]System.Drawing.Rectangle
IL_0012: ldobj [System.Drawing]System.Drawing.Rectangle
IL_0017: stloc.0

Looks much simpler except the lines IL_0011 through IL_001b are only
executed if the array element is NULL. Since using DirectCast you need to
check for NULL anyway, there is absolutely no difference.

The surprising thing is that CType(xxx, Int32) or to any other simple
type, results in a rather complex call to
Microsoft.VisualBasic.CompilerServices.XXConverter, that tries to cast to
IConvertible and perform the conversion, rather than a cast. Not exactly
surprising, since CType is supposed to mimic VB6 CType, i.e. convert a
value by any means possible short of starting WWIII, but somewhat
disappointing

--
Alex Feinman
---
Visit http://www.opennetcf.org
Daniel Moth said:
Thanks for that... sounds like my reference and value types are getting
mangled... my rule is still the same however: Never use CType over
DirectCast unless you really need to <g>

Look at these two in ildasm to see where I was coming form...

Dim ar As New ArrayList()
Public Sub MyMethod()
Dim o As Int32 = CType(ar.Item(0), Int32)
End Sub

Public Sub MyMethod2()
Dim o As Int32 = DirectCast(ar.Item(0), Int32)
End Sub

The outcome of some measurements I did a while back when
converting/casting a double in VB, are in the comments section here:
http://blogs.msdn.com/bclteam/archive/2005/02/11/371436.aspx

Cheers
Daniel
 
Back
Top