tags:

views:

911

answers:

5

This is probally more of an elegance question than functionality. I am looking for the absolutely safest way to check for an integer from a string and an object,

Using most of the built in functions for this in .net seem to generate a first chance exception, displayed in the Immediate window, and over time they just build up. what are the implications of these exceptions as they don't seem to affect the operation of the system.

Here are my two attempts, both feel clunky and I know there has to be a better way than using VB.IsDBNull and Integer.TryParse... Or am I just being anal.

(to integer from object)

    Dim nInteger As Integer = 0
    If oData Is Nothing OrElse VB.IsDBNull(oData) Then
    Else
        If bThrowErrorIfInvalid Then
        Else
            On Error Resume Next
        End If
        nInteger = CType(oData, Integer)
    End If
    Return nInteger

(to integer from string)

    Dim nInteger As Integer = 0
    If sText Is Nothing Then
    Else
        If bThrowErrorIfInvalid Then
        Else
            On Error Resume Next
        End If
        Integer.TryParse(sText, nInteger) 
    End If
    Return nInteger
A: 

You can try this:

Dim i as Integer
Try
    i = Convert.ToInt32(obj)
Catch
    ' This ain't an int
End Try

Convert is in the System namespace.

EDIT: Note: If you are going to put any other code in the Try block, make sure to specify that the only exception the Catch should catch is the exception thrown by Convert.ToInt32 if/when it fails - otherwise you could end up with a nasty problem if something else in that try/catch should fail.

Fritz H
I realise I could use a try catch but I want to find a completly safe method so I dont have to, the reason being this is for a Common Lib and and is used A LOT. Also Im looking for an elegant solution, try catch seems like a hit and hope approach..
CodeKiwi
The idea is that Convert.ToInt32 will always throw an exception if the conversion failed - and the beauty is that it can take all kinds of objects so you don't need to convert it first. To make it elegant you need to specify the Convert's exception type to catch, though.
Fritz H
I agree that the Convert.x mechinism is fantastic and until now I have used it religiously, however I believe try catch is making me lazy (hense this question), it works so why do I need to think.
CodeKiwi
Exceptions are bad for performance.
amdfan
+7  A: 

Whats wrong with using the Integer.TryParse? Thats what it was made for...

int i = 0;
string toTest = "not number";
if(int.TryParse(toTest, out i))
{
   // it worked

}

How is that clunky? (C# not VB i know, but same diff)

EDIT: Added if you want to check from an object as well (since TryParse relies on a string) and im not too sure on how you actually plan to use it. Does that cover your concerns a little since this one method will check for both of your cases?

    static bool TryParseInt(object o, out int i)
    {
        i = 0;

        if (o.GetType() == typeof(int))
        {
            i = (int)o;
            return true;
        }
        else if (o.GetType() == typeof(string))
        {
            return int.TryParse(o as string, out i);
        }

        return false;
    }
RM
It is pretty similar to my second example(and how I have currently implemented it), it is the only method I found that wouldnt generate an error during the conversion, It just doesnt seem right I think I might be just being anal.
CodeKiwi
It is right. It should seem right.
matt b
I've added another sample method, showing how it can cater for object type and string type for checking for int. Hopefully that helps eleviate your concerns...
RM
I liked that second example, I think that has the elegance I was talking about. Thanks.
CodeKiwi
What if the object is something other than a string or integer? This version of TryParseInt wouldn't handle that situation. For example, a nullable integer will most definitely convert to an integer, but this would exclude it. It will also throw an exception if o is null.
Jeromy Irvine
CodeKiwi
@Jeromy - Actually using a nullable int is fine.Nullable<int> k = 12;Console.WriteLine(TryParseInt(k, out x) + " " + x); // Prints True 12You are correct for a null being passed in, that will cause an issue with the example above, a basic null check inside / outside will solve that one.
RM
@Mainstay - Makes sense, I didn't have a compiler available to test it last night.
Jeromy Irvine
+1  A: 

Integer.TryParse is designed to be the safe way to do this: that's why it was put into the framework in the first place. For an Object, you could always just call ToString() before using TryParse.

I'd also avoid using On Error Resume Next in favor of a Try-Catch block if you need to swallow an error for some reason, as it's much less likely to cause an unwanted side effect.

Jeromy Irvine
Are there any performance implications of using Try Catch.
CodeKiwi
I'm not sure if there's a difference between Try-Catch and Resume-Next, but I wouldn't expect there to be much, and even if there is, it's probably worth the hit to make the code more robust.
Jeromy Irvine
Sometimes there are, but the performance implications of "On Error" are greater.
Jimmy
A: 

Since it's VB you can also use the IsNumeric function

Jacob Adams
IsNumeric only tells me if it "Is numeric", it does not perform any converstion
CodeKiwi
Well, the question just says to check for an integer. If you want to do the conversion, you just pair it with any standard conversion/casting function like Convert.ToInt32,CInt, Integer.Parse, etc.
Jacob Adams
A: 

it seems in your second example, you have a unnecessary check for bThrowErrorIfInvalid because Integer.TryParse never throws an error. Something Like

If bThrowErrorIfInvalid And Not Integer.TryParse(sText, nInteger) Then
   Throw New ArgumentException()
EndIf
Jimmy
Of course if all you're doing when it's an invalid integer is throwing an ArgumentException, just use Interger.Parse instead, and let it throw that exception for you
Yuliy
hmmm, good spotting.
CodeKiwi