Reputation: 861
I was just wondering how to correctly
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
Reputation: 38905
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