Option Strict and Data Type Conversion

LeonR

Well-known member
Joined
Nov 2, 2006
Messages
139
Location
UK
Programming Experience
10+
Just wondering what the preferred/practised data type conversion technique is?

For example I recently enabled option strict, which in turn found quite a few errors in relation to data types, vb.net prompted me to use CType, which is fine.

However, I have seen other functions for data type conversion, such as .tostring, CInt , Convert, integer.parse and also Ctype.

Why would you use Ctype over the others?


I know its a pretty primitive question , but why do so many conversion methods exist?
 
If you're converting from say a string to a numeric type (like an integer, double, decimal) or to DateTime, then you should use <type>.TryParse()
For example:
VB.NET:
  Dim SomeNumber As Integer
  Integer.TryParse("123", SomeNumber) 'SomeNumber now equals 123

If you have an object (integer, decimal, some class) and you need a string representation of it, just call it's .ToString()
For example:
VB.NET:
  Dim MyNumber As Integer = 123I
  Dim StringNumber As String = MyNumber.ToString()

If you have an object that you know is actually a button or a textbox, etc (take the sender parameter for example) and you simply need to tell the compiler that the object is really a button, that's when I use either DirectCast() or CType()
For example:
VB.NET:
  Private Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button1.Click, Button2.Click, Button3.Click
    'Could be any of the three buttons, but we don't care as we'll just use sender

    Dim btn As Button = CType(sender, Button) 'Tell the compiler that sender really is a button

    'Use btn in following code.....
  End Sub
 
why do so many conversion methods exist?
Because there are several base data types and conversion is possible between most of them. The type system is also extensible, in that you can define your own types, so there exist functionality to provide conversions for these as well. I willl highlight some of these a bit more in depth, still as a general overview, but I recommend you 'take the tour' with the relevant help topics in documentation also.

CType is a general function where second parameter can be any target type. It is also compiled inline, which means the conversion is determined by the compiler directly. The type specific counterparts is all the C-functions like CInt, CStr etc. When you write code and want to do such a conversion it is easier to write CInt(value) rather than CType(value, Integer). These functions are also refered to as operators in the way they operate. For custom types you can define custom CType operators, and they will work with the CType functions as well.

DirectCast does not convert the value, it will only convert how you see the type of object based on inheritance or interface implementation. DirectCast relationships are also evaluated by the compiler when possible, but without the value conversions it can operate faster. Related conversions to this are TryCast and Enumerable.Cast(Of T).

The Convert class offer conversions between base types, these are regular function calls, for example Convert.ToInt32(value). Convert class also has a general ChangeType function where the second parameter is a Type reference, this is different from the inline CType function, an example for illustration is Convert.ChangeType(value, GetType(Integer)). This also does not have the compile time support like CType, and the return type is Object, while CType can be inferred. Conversion from a custom type to base types can be implemented through the IConvertible interface, which will work with the Convert class, or directly (type cast) through that interface.

Custom conversion can also be provided by defining a TypeConverter, this is commonly used for string conversions in component development for design time support. All base data types also have a TypeConverter defined for them.

Parsing (analysing) means converting from a string to a value of some type, and since a string can be used to describe and represent anything the operation is very much one of analysing the content and its format. All base types includes these Parse functions, and they throw exceptions at runtime if the operation fails. The TryParse variety does the same conversion, but does not throw exceptions for valid operations, a Boolean value signifies the success or failure and the possible converted value is returned with a ByRef parameter. This is also a simplification in coding to using a Try-Catch block when something has a probability to fail without other means to prevent it. When converting string data that you are not in control of, for example something written by a user, the TryParse methods is usually the best option.

ToString is a special deal, everything you read on screen are strings, to be displayed any type of value needs to be converted to a string, while in memory everything is stored in a binary format. For this reason the base type Object has the overridable ToString method, any type can override this to provide a custom string representation of its value. The base types also has overloads of this with parameters that allow more control over the display format, two of which are implementations of IConvertible.ToString and IFormattable.ToString. ToString is an instance method, which makes it good in OOP perspective and an intuitive .(dot) extention when you're coding. One problem with this is if you have a variable that at runtime may not point to an object, if the variable is currently a null reference (Nothing) the instance call .ToString will throw an exception (ie no instance exist to call the method on). These are not direct equivalents by the way, even though for base types CStr/CType will return same string value as the default ToString. If you in a custom type decide to implement a CType operator to String it would be a good idea to return same value as your ToString override as they are often used interchangably by users.

FromString? That is usually a parsing method, but there are many examples of type specific conversion methods using the 'From' naming convension. Try for example a 'from' search in the Object Browser.

A more obscure conversion exists in the BitConverter class, that converts between base types and its bytes representation. It is also sometimes used along with the BitArray class for manipulation of values in their binary form.
 
Back
Top