VB.NET Conversions

Tags: .NET, .NET Framework, VB.NET

 

There was some discussion around the office which touched on the topic for the best method for object conversion in VB.NET. 

Given this (typical) pattern:

   1: Dim sneakers As Cat = CType(Factory.GetObject(someKey), Cat)
   2:  
   3: If (sneakers Is Nothing) Then
   4:  ...
   5: End If

I personally have always felt that CType was not the preferred method, so I decided to do some digging.

Lets start with the basic performance test, the sample code…

   1: Dim max As Integer = 1000000
   2: Dim sw As New System.Diagnostics.Stopwatch
   3: Dim duration As TimeSpan
   4: sw.Start()
   5: For index As Integer = 1 To max
   6:     Dim MyObject As Object = "Hello World"
   7:     Dim MyString1 As String = CType(MyObject, String)
   8: Next
   9: duration = New TimeSpan(sw.ElapsedTicks)
  10: Console.WriteLine("CType Value Type to Object:{0:0.00000}", duration.TotalMilliseconds)
  11: sw.Reset()
  12:  
  13: sw.Start()
  14: For index As Integer = 1 To max
  15:     Dim MyObject As Object = "Hello World"
  16:     Dim MyString1 As String = DirectCast(MyObject, String)
  17: Next
  18: duration = New TimeSpan(sw.ElapsedTicks)
  19: Console.WriteLine("DirectCast Value Type to Object:{0:0.00000}", duration.TotalMilliseconds)
  20: sw.Reset()
  21:  
  22: sw.Start()
  23: For index As Integer = 1 To max
  24:     Dim MyObject As Object = "Hello World"
  25:     Dim MyString1 As String = TryCast(MyObject, String)
  26: Next
  27: duration = New TimeSpan(sw.ElapsedTicks)
  28: Console.WriteLine("TryCast Value Type to Object:{0:0.00000}", duration.TotalMilliseconds)
  29: sw.Reset()
  30:  
  31:  
  32: sw.Start()
  33: For index As Integer = 1 To max
  34:     Dim MyObject As New Cat
  35:     Dim MyString1 As Cat = CType(MyObject, Cat)
  36: Next
  37: duration = New TimeSpan(sw.ElapsedTicks)
  38: Console.WriteLine("CType Ref type to Object:{0:0.00000}", duration.TotalMilliseconds)
  39: sw.Reset()
  40:  
  41: sw.Start()
  42: For index As Integer = 1 To max
  43:     Dim MyObject As New Cat
  44:     Dim MyString1 As Cat = DirectCast(MyObject, Cat)
  45: Next
  46: duration = New TimeSpan(sw.ElapsedTicks)
  47: Console.WriteLine("DirectCast Ref type to Object:{0:0.00000}", duration.TotalMilliseconds)
  48: sw.Reset()
  49:  
  50: sw.Start()
  51: For index As Integer = 1 To max
  52:     Dim MyObject As New Cat
  53:     Dim MyString1 As Cat = TryCast(MyObject, Cat)
  54: Next
  55: duration = New TimeSpan(sw.ElapsedTicks)
  56: Console.WriteLine("TryCast Ref type to Object:{0:0.00000}", duration.TotalMilliseconds)

 

And the output it yields:

CType Value Type to Object:3.95910
DirectCast Value Type to Object:1.17570
TryCast Value Type to Object:1.07470
CType Ref type to Object:7.62320
DirectCast Ref type to Object:6.41400
TryCast Ref type to Object:6.58750

Notice that CType consistently performs worse than both DirectCast and TryCast in both usage scenarios (By Value and by Reference).

Ok, so now we all know to avoid CType and prefer either DirectCast or TryCast.  The next logical question is…

What is the difference between DirectCast and TryCast and which one should we use for this situation.

The answer will come from the documentation for VB.NET.  At the time of writing this, the URL for the answer can be found here: http://msdn.microsoft.com/en-us/library/zyy863x8%28VS.80%29.aspx

Here is a snippet of the page, I bolded the significant portions:

If an attempted conversion fails, CType and DirectCast  both throw an InvalidCastException  error. This can adversely affect the performance of your application. TryCast  returns Nothing (Visual Basic), so that instead of having to handle a possible exception, you need only test the returned result against Nothing.

You use the TryCast keyword the same way you use the CType Function and the DirectCast keyword. You supply an expression as the first argument and a type to convert it to as the second argument. TryCast operates only on reference types, such as classes and interfaces. It requires an inheritance or implementation relationship between the two types. This means that one type must inherit from or implement the other.

Method Types Throws
CType Any InvalidCastException
DirectCast Any InvalidCastException
TryCast Reference Only None

 

So, since our specific scenario deals with reference types, our preferred method would be to use TryCast.  In any other case we will be forced to use DirectCast and remember to watch out for that costly InvalidCastException.

Side Note: If you noticed that we are actually using a String (value type) with TryCast and we are not seeing any compile time error, this is due to the fact that since the ToString() method is defined for all objects, you will always be able to cast to a string.

No Comments