testing if a string can be cast as a integer in VB.NET
Is there a better way of testing if a string can be converted to an integer other than something like the following?
Public Function IsInt(ByVal value As Object) As Boolean
Try
Dim temp As Integer = CInt(value)
Return True
Catch ex As Exception
Return False
End Try
End Function
by "better" I mean less verbose and/or w/o an exception.
TryParse would be the way to go, but I'm using the compact framework 2.0 and tryparse doesn't seem to be implemented....
Thanks anyways.
It seems that MarkJ is correct and the above seems to be functionally the same as IsNumeric, so I suppose that's my answer. I don't know why I thought CInt was more strict than I开发者_StackOverflow中文版sNumeric. I guess it's better to test using CInt verses IsNumeric since that's the function I'm using to do the conversion?
You can use the built in IsNumeric Function
Dim CanConvert as Boolean = IsNumeric(value)
http://msdn.microsoft.com/en-us/library/6cd3f6w1(VS.71).aspx
Since TryParse isn't supported on the Compact Framework, regex is your next best option.
The first example doesn't allow decimals. The second one does.
Regex.IsMatch(value, "^-?\d+$")
Regex.IsMatch(value, "^-?\d+(?:\.\d+)?$")
If you need to allow for scientific notation, you need to tweak it a little more. It really just isn't that bad. You've got the beginning of the string ^
, an optional dash -?
, one or more digits \d+
, a non-capturing group (?:)
that looks for a single decimal point \.
and one or more digits \d+
. Another ?
to allow either zero or one instances of the non-capturing group, and then the end of the string $
.
Edit:
One thing I didn't think about before: this method is a little imprecise because you could get a really huge number that is numerically a valid integer but can't be converted to an Int32. If that's a possibility, you could constrain the number of characters. Instead of \d+
, you could do \d{1,8}
, for example.
Public Function IsInt(ByVal value As Object) As Boolean
Dim i As Integer
Return Integer.TryParse(Convert.ToString(value), i)
End Function
you can use Integer.TryParse
, which will return a bool indicating whether the conversion was successfull or not
well if you want to avoid using exceptions you could match it against a regular expression that allows only digit characters before converting.
If you're only performing the conversion infrequently, what you have is fine (assuming there's no TryParse()
available to you) - it's not going to affect performance.
If you're going to perform millions of conversions, and a large number of them might fail then the exception you're catching could be a perf issue (maybe).
If you can't use TryParse() probably the best thing to do (perf-wise) is to simply check each character in the string and if it's not a digit return false. Don't forget to account for a possible negative sign and group separators (if you want to support them).
Otherwise, parse the string to an int, which will succeed in 99% of the cases. you'll only get an exception if it won't fit. If you really want to avoid the exception that Parse() might generate, it's not hard to actually parse the sting of digits yourself, and return failure if it goes out of range.
Jon Skeet did a quick analysis of this back before the Framework contained TryParse()
:
- Checking if a string can be converted to Int32
None of this fixes the verbosity, though. but as long as it's a self-contained method, there's no real problem with a little verbosity.
Dim s as String = "23"
Dim i as Integer
If Int32.TryParse(s, i) Then
' String was a valid integer... '
End If
Use the TryParse shared method of the Integer type.
For example:
Private Function CanStringBeCastAsInteger(ByVal myString As String) As Boolean
Dim myInt As Integer = 0
Return Integer.TryParse(myString, myInt)
End Function
The benefit of using the TryParse method is that it avoids having to throw and subsequently catch an Exception when the cast fails. Throwing and catching exceptions is an expensive operation.
Not only will the TryParse method return a True/False result, telling you if the conversion will succeed or not, it will also return, in the myInt parameter in my example, the resulting conversion for you, all in one line of code.
Here is something very similar to what you have already but uses the Convert class instead of CType and does not use TryParse
Public Function IsInt(ByVal value As Object) As Boolean
Try
Convert.ToInt32(value)
Return True
Catch ex As System.FormatException
Return False
End Try
End Function
You'd need to roll your own regex e.x.: Regex.IsMatch("4354354", "\d+"), and still include the try/catch block as a backup.
Do as follow
If myString <> "" And IsNumeric(myString) = True Then
If CDbl(myString) - Int(CDbl(myString)) > 0 Then
.... myString is integer
End If
End If
精彩评论