bbesase
bbesase

Reputation: 861

Converting DataTypes for Option Strict

I was just wondering how to correctly

  1. Convert string to date
  2. Convert integer to short
  3. Convert string to integer
  4. Convert string to double

correctly without using any Ctypes of any sort. I turned on Option Strict and now all these errors popped up so I'm trying to fix them :)

Upvotes: 1

Views: 3865

Answers (1)

NET provides several ways to check, test and convert data.

TryParse

This is perhaps the most bulletproof way to convert. It is ideal for validating user input:

Dim n As Int32
If Int32.TryParse(TextBox.Text, n) Then
    ' work with n
Else
    ' error handling: TextBox.Text cannot convert to int
End If

All the core datatypes support it (Int64, Decimal, Date etc). It is different from others: it does not return the converted value, but a Boolean indicating whether the source string could be converted to a variable.

Parse

Dim d as Double = Double.Parse(strVar) 

This is ok to use when your code created strVar and you know it contains numerals and not punctuation etc. Parse and TryParse both allow you to parse data from other cultures by providing a FormatProvider and other options:

Dim strDec = "$ 123.45"
Dim decVal As Decimal = Decimal.Parse("$123.45", NumberStyles.Currency)

Other methods will choke on the "$", the style argument allows it.

Convert.ToInt32 / Convert.ToInteger

This one has many, many overloads:

Dim intV As Int32 = Convert.ToInt32(aString)
Dim dblV As Double = Convert.ToDouble(aString)
Dim lngV As Int64 = Convert.ToInt64(aString)

The Convert.Toxxx methods are slightly less specialized than the ones above. They allow culture conversions, but they assume a direct conversion is possible. That is, "123" will convert to integer, but not "123.45" and it wont know anything thing like currency formats.

So, use this when you know the value can convert, perhaps because you converted the value to string. These also work to unbox objects from a database DataReader:

myDT = Convert.ToDateTime(rdr("BirthDate"))
myV = Convert.ToInt32(rdr("FooValue"))

Provided the data is actually stored as those types and "boxed" as Object for the DBDataReader, Convert will work fine. (Note that DBDataReaders can return typed data directly: n = rdr.GetInt32(1) but you cannot use the column name, just the ordinal position).

CInt, CSng...etc

CInt is similar to Convert.ToInteger, but according to MSDN optimized for use in VB. For instance:

a = Convert.ToInt32("123.50")     ' exception due to decimal point
a = CInt("123.50")                ' a = 124

Confusing? Yes, but once you get a handle on them, you can use the method which best fits the situation. There is no way to specify a culture for CInt, CDec etc.

Val

Don't use Val. Ever. It is a very generic function which returns a Double. Using it can result in all sorts of undesirable Type conversions:

Dim n = Val(tbSmallValue.Text)

n is created as a Double so if the textbox was "5", then n = 5.0. When n is used where an integer is expected (such as inserting into a database) errors can happen. The result varies greatly:

dd = Val("123.4")          ' = 123.4
dd = Val("$123.45")        ' = 0.0
dd = Val("123abc")         ' = 123.0

NB CInt and Convert.ToInt32 implement "Banker's Rounding" where .50 fractions are rounded to the nearest even number. 123.50 and 124.50 both round/convert to 124.

Upvotes: 2

Related Questions