1

I don't like having to do something like this every time I use CInt or Integer.Parse (which I realize is costly):

Try
  someIntVariable = CInt(someStringVariable)
Catch ex As Exception
  someIntVariable = 0
End Try

And I don't like all the lines of code involved with Integer.TryParse. I guess I could create a function that does something like:

Function ToInteger(str As String) As Integer
  Dim number As Integer
  Int32.TryParse(str, number)
  Return number
End Function

But isn't there already an extension method or something built into .NET that can do this for me in a more elegant way (along the lines of Nullable(Of T).GetValueOrDefault)?

Daniel
  • 10,864
  • 22
  • 84
  • 115
  • You may want to look at this post: [Integer.TryParse - a better way?](http://stackoverflow.com/questions/419027/integer-tryparse-a-better-way). TryParse won't throw an exception and as a result works much faster. – Artemix May 10 '13 at 14:46
  • Um. Maybe check the documentation for [`TryParse`](http://msdn.microsoft.com/en-us/library/f02979c7.aspx): "*result* ... When this method returns ... zero if the conversion failed" - it sounds like it's already the function you want. (`Double.TryParse` is similarly defined to return zero on failure) – Damien_The_Unbeliever May 10 '13 at 14:50
  • 1
    Since `0` is the default value of `Integer`, you could just omit the entire `If/Else`-block in your method, since when the conversion fails, `TryCast` will set `number` to `0`. – sloth May 10 '13 at 14:51

4 Answers4

7

Honestly Integer.TryParseis the way to go, but you can always hide it behind an extension method if you do not like the syntax.

Public Module IntegerExtensions
    <Extension()> _
    Public Function AsIntOrDefault(ByVal valueToParse As String, Optional ByVal defaultValue As Integer = 0) As Integer
        Dim retVal As Integer = 0

        If Not Integer.TryParse(valueToParse, retVal) Then
            retVal = defaultValue
        End If

        Return retVal
    End Function
End Module

Which can then be used like this:

Public Class Foo
    Public Sub Blah()
        Dim value1 As Integer = "IWillNotParse".AsIntOrDefault() 'Should be 0
        Dim value2 As Integer = "IWillNotParse".AsIntOrDefault(5) 'Should be 5
        Dim value3 As Integer = "123".AsIntOrDefault() 'Should be 123
    End Sub
End Class
avanek
  • 1,649
  • 12
  • 20
  • +1 good extension method, which is just using `TryParse` and hiding it.... seems to be what the OP wants.... – Matthew May 10 '13 at 15:33
  • 1
    You do not need the If Not statement. See my answer. – Alex Wiese May 10 '13 at 22:52
  • @alexw - Actually, you do: ` Public Class TryParseTests Public Sub TryParseTest() Dim foo As Integer = 5 Integer.TryParse("NoGood", foo) Assert.AreEqual(5, foo) End Sub End Class ` _Assert.AreEqual failed. Expected:<5>. Actual:<0>._ If you look at the Number class in the .NET framework, it sets the `out result` argument to 0 before it attempts to parse the string. – avanek May 13 '13 at 12:22
  • @avanek that is correct but the question is "best way to default to 0", therefore a simple `TryParse` is all that is required. – Alex Wiese May 13 '13 at 23:14
  • For my particular implementation it is needed. We're splitting hairs here. If I were to remove my optional parameter, you are absolutely correct. Still, I'm hesitant to lean on a side-effect of an external method. It's the same reason why I prefer `string.Empty` over `""`. Who knows when it could change to something else? Never say never, ha. – avanek May 14 '13 at 12:29
5

You should not use try/catch if you don't need to. There is a lot of overhead involved in throwing an exception.

Instead you can simply use this code (no if/end if statement)

Dim value As Integer = 0
Int32.TryParse(stringValue, value)

If the string is parse-able then you will have the value, otherwise 0.

Alex Wiese
  • 8,142
  • 6
  • 42
  • 71
  • Nobody reads the question. As I said, I don't want to use TryParse. Its implementation feels hacky for this purpose. I'll write my own extension method. – Daniel May 10 '13 at 14:55
  • 3
    How is TryParse hacky? It exists for the exact problem you describe! – Alex Wiese May 10 '13 at 14:56
  • So how will your extension method work? With a try/catch or TryParse? – Alex Wiese May 10 '13 at 14:57
  • 4
    @Doc - people have read your question. Before your edit, your `TryParse` method was overly lengthy given that the behaviour of `TryParse` is to set the result to zero on failure, which is exactly what you seem to be asking for. – Damien_The_Unbeliever May 10 '13 at 14:58
  • I'd like to be able to do something like `intvar = stringvar.ToIntOrDefault()` – Daniel May 10 '13 at 14:58
  • 2
    @doc and would that extension method use the TryParse method like in my example? Or would you still use the slower try/catch method? – Alex Wiese May 10 '13 at 14:59
  • I realize try/catch is costly. I guess I'm just so used to working with all the built-in extension methods that I was hoping there would be something along those lines that I was missing. – Daniel May 10 '13 at 15:19
  • 2
    @Doc `TryParse` is the framework solution to your problem. If you want a one liner you'll have to define your own method (which should just use `TryParse` – Matthew May 10 '13 at 15:26
  • What avanek posted is what you want. – dbasnett May 10 '13 at 15:27
1

Maybe this could work for you..

Function ToInteger(str As String) As Integer
    Dim number As Integer
    If IsNumeric(str) Then
        number = CInt(str)
    Else
        number = 0
    End If
    Return number
End Function
Rose
  • 641
  • 7
  • 17
  • `IsNumeric` is an old VB6 function which is still supported in .NET, but primarily for backwards compatibility. It's best to avoid those methods when possible. Also, `CInt` could fail for other reasons. For instance, it could be numeric, but the number could be too large to convert it to an `Integer`. – Steven Doggart May 10 '13 at 16:46
0

Try out Integer.TryParse(String, Integer)

You pass the String you want to parse, and the Integer you want to store the result in.

TryParse returns a Boolean with whether the parse succeeded or failed. So you could do

If Not Integer.TryParse(myNonInt, DestinationInt)
    DestinationInt = 0
End If

If the parse succeeds, the value automatically gets stored in DestinationInt.

Chris Stauffer
  • 352
  • 1
  • 8
  • +1 not sure why you were downvoted except there is no need to set the value if it fails, integers already default to zero. – Matthew May 10 '13 at 15:13