Casting and Data Type Conversions in VB.NET

Man in profile working on a laptop.

vgajic / Getty Images

Casting is the process of converting one data type to another. For example, casting an Integer type to a String type. Some operations in VB.NET require specific data types to work. Casting creates the type you need. The first article in this two-part series, Casting and Data Type Conversions in VB.NET, introduces casting. This article describes the three operators you can use to cast in VB.NET - DirectCast, CType and TryCast - and compares their performance.

When to Use Different Casting Operations

Performance is one of the biggest differences between the three casting operators, according to Microsoft and other articles. For example, Microsoft is usually careful to warn that, "DirectCast ... can provide somewhat better performance than CType when converting to and from data type Object." (Emphasis added.)

I decided to write some code to check.

But first, a word of caution. Dan Appleman, one of the founders of the technical book publisher Apress and a reliable technical guru, once told me that benchmarking performance is much harder to do correctly than most people realize. There are factors like machine performance, other processes that might be running in parallel, optimization like memory caching or compiler optimization, and errors in your assumptions about what the code is actually doing. In these benchmarks, I have tried to eliminate "apples and oranges" comparison errors and all tests have been run with the release build. But there still might be errors in these results. If you notice any, please let me know.

The three casting operators are:

  • DirectCast
  • CType
  • TryCast

DirectCast

In practical fact, you will usually find that the requirements of your application will determine which operator you use. DirectCast and TryCast have very narrow requirements. When you use DirectCast, the type must already be known. Although the code ...

theString = DirectCast(theObject, String)

... will compile successfully if the Object isn't a string already, then the code will throw a runtime exception.

TryCast

TryCast is even more restrictive because it won't work at all on "value" types such as Integer. (String is a reference type. For more on value types and reference types, see the first article in this series.) This code ...

theInteger = TryCast(theObject, Integer)

... won't even compile.

TryCast is useful when you're not sure what type of object you're working with. Rather than throwing an error like DirectCast, TryCast just returns Nothing. The normal practice is to test for Nothing after executing TryCast.

CType

Only CType (and the other "Convert" operators like CInt and CBool) will convert types that don't have an inheritance relationship such as an Integer to a String:

Dim theString As String = "1"
Dim theInteger As Integer
theInteger = CType(theString, Integer)

This works because CType uses "helper functions" that aren't part of the .NET CLR (Common Language Runtime) to perform these conversions.

But remember that CType will also throw an exception if the String doesn't contain something that can be converted to an Integer. If there's a possibility that the string isn't an integer like this ...

Dim theString As String = "George"

... then no casting operator will work. Even TryCast won't work with Integer because it's a value type. In a case like this, you would have to use validity checking, such as the TypeOf operator, to check your data before trying to cast it.

Performance Test

Microsoft's documentation for DirectCast specifically mentions casting with an Object type, so that's what I used in my first performance test. Testing begins on the next page!

DirectCast will usually use an Object type, so that's what I used in my first performance test. To include TryCast in the test, I also included an If block since nearly all programs that use TryCast will have one. In this case, however, it will never be executed.

Here's the code that compares all three when casting an Object to a String:

Dim theTime As New Stopwatch()
Dim theString As String
Dim theObject As Object = "An Object"
Dim theIterations As Integer =
CInt(Iterations.Text) * 1000000
'
' DirectCast Test
theTime.Start()
For i = 0 To theIterations
theString = DirectCast(theObject, String)
Next
theTime.Stop()
DirectCastTime.Text =
theTime.ElapsedMilliseconds.ToString
'
' CType Test
theTime.Restart()
For i As Integer = 0 To theIterations
theString = CType(theObject, String)
Next
theTime.Stop()
CTypeTime.Text =
theTime.ElapsedMilliseconds.ToString
'
' TryCast Test
theTime.Restart()
For i As Integer = 0 To theIterations
theString = TryCast(theObject, String)
If theString Is Nothing Then
MsgBox("This should never display")
End If
Next
theTime.Stop()
TryCastTime.Text =
theTime.ElapsedMilliseconds.ToString

This initial test seems to show that Microsoft is right on target. Here's the result. (Experiments with larger and smaller numbers of iterations as well as repeated tests under different conditions didn't show any significant differences from this result.)

DirectCast and TryCast were similar at 323 and 356 milliseconds, but CType took over three times as much time at 1018 milliseconds. When casting reference types like this, you pay for the flexibility of CType in performance.

But does it always work this way? The Microsoft example in their page for DirectCast is mainly useful for telling you what won't work using DirectCast, not what will. Here's the Microsoft example:

Dim q As Object = 2.37
Dim i As Integer = CType(q, Integer)
' The following conversion fails at run time
Dim j As Integer = DirectCast(q, Integer)
Dim f As New System.Windows.Forms.Form
Dim c As System.Windows.Forms.Control
' The following conversion succeeds.
c = DirectCast(f, System.Windows.Forms.Control)

In other words, you can't use DirectCast (or TryCast, although they don't mention it here) to cast an Object type to an Integer type, but you can use DirectCast to cast a Form type to a Control type.

Let's check the performance of Microsoft's example of what will work with DirectCast. Using the same code template shown above, substitute ...

c = DirectCast(f, System.Windows.Forms.Control)

... into the code along with similar substitutions for CType and TryCast. The results are a little surprising.

Results

DirectCast was actually the slowest of the three choices at 145 milliseconds. CType is just a little quicker at 127 milliseconds but TryCast, including an If block, is the quickest at 77 milliseconds. I also tried writing my own objects:

Class ParentClass
...
End Class
Class ChildClass
Inherits ParentClass
...
End Class

I got similar results. It appears that if you're not casting an Object type, you're better off not using DirectCast.

Format
mla apa chicago
Your Citation
Mabbutt, Dan. "Casting and Data Type Conversions in VB.NET." ThoughtCo, Jul. 29, 2021, thoughtco.com/casting-and-data-type-conversions-vbnet-3424292. Mabbutt, Dan. (2021, July 29). Casting and Data Type Conversions in VB.NET. Retrieved from https://www.thoughtco.com/casting-and-data-type-conversions-vbnet-3424292 Mabbutt, Dan. "Casting and Data Type Conversions in VB.NET." ThoughtCo. https://www.thoughtco.com/casting-and-data-type-conversions-vbnet-3424292 (accessed March 28, 2024).