50

Possible Duplicate:
How to identify if string contain a number?

In VB there's an IsNumeric function, is there something similar in c#?

To get around it, I just wrote the code:

    if (Int32.Parse(txtMyText.Text.Trim()) > 0)

I was just wondering if there is a better way to do this.

Community
  • 1
  • 1
user1202606
  • 1,160
  • 9
  • 23
  • 37

7 Answers7

87

You could write an extension method:

public static class Extension
{
    public static bool IsNumeric(this string s)
    {
        float output;
        return float.TryParse(s, out output);
    }
}
Otávio Décio
  • 73,752
  • 17
  • 161
  • 228
  • 8
    I'd rather call that method `IsInteger`. Numeric is pretty ambiguous. – CodesInChaos Mar 21 '12 at 17:05
  • 3
    @CodeInChaos - sure, why not. I wouldn't call the class Extension either, I was more concerned with the idea. – Otávio Décio Mar 21 '12 at 17:09
  • This method returns `false` for several classes of string for which `IsNumeric` returns `true`. – phoog Mar 21 '12 at 17:27
  • @phoog - Let's make it float then. – Otávio Décio Mar 21 '12 at 17:40
  • 1
    That wouldn't duplicate the behavior for strings like `"$100"`. – phoog Mar 21 '12 at 17:42
  • 5
    @phoog - I wasn't trying to duplicate anything, just offering a better alternative than calling Int32.Parse all the time. Please feel free to write a replacement if you feel inclined and share it with us. – Otávio Décio Mar 21 '12 at 17:43
  • Your alternative is certainly better and it probably fits the OP's needs, though we don't really have enough information to know that for sure. (I have already posted my own answer, which is to call the IsNumeric function from C# code.) – phoog Mar 21 '12 at 17:47
  • 1
    Or in a one liner ```return float.TryParse(s, out _);``` with c# 7.0 – Siva Kandaraj Jul 12 '18 at 03:54
19

You should use TryParse - Parse throws an exception if the string is not a valid number - e.g. if you want to test for a valid integer:

int v;
if (Int32.TryParse(textMyText.Text.Trim(), out v)) {
  . . .
}

If you want to test for a valid floating-point number:

double v;
if (Double.TryParse(textMyText.Text.Trim(), out v)) {
  . . .
}

Note also that Double.TryParse has an overloaded version with extra parameters specifying various rules and options controlling the parsing process - e.g. localization ('.' or ',') - see http://msdn.microsoft.com/en-us/library/3s27fasw.aspx.

MiMo
  • 11,793
  • 1
  • 33
  • 48
  • `Int32.TryParse` returns `false` for `1E2`, for example, while `IsNumeric` returns `true`. – phoog Mar 21 '12 at 17:28
  • There is `Double.TryParse` then - I am updating my answer – MiMo Mar 21 '12 at 17:46
  • According to the documentation Parse and TryParse ignore whitespace. This makes the Trim() unnecessary. https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/types/how-to-convert-a-string-to-a-number – Dawied Nov 02 '17 at 12:38
  • Keep in mind the max value for Int is 2147483647. You might consider using long (9223372036854775807) or ulong (18446744073709551615) to support larger numbers. – Francisco d'Anconia Aug 14 '20 at 16:56
17

I think you need something a bit more generic. Try this:

public static System.Boolean IsNumeric (System.Object Expression)
{
    if(Expression == null || Expression is DateTime)
        return false;

    if(Expression is Int16 || Expression is Int32 || Expression is Int64 || Expression is Decimal || Expression is Single || Expression is Double || Expression is Boolean)
        return true;

    try 
    {
        if(Expression is string)
            Double.Parse(Expression as string);
        else
            Double.Parse(Expression.ToString());
            return true;
        } catch {} // just dismiss errors but return false
        return false;
    }
}

Hope it helps!

Reinaldo
  • 4,556
  • 3
  • 24
  • 24
  • This is a much better answer than all the others, but it still doesn't match the functionality of `IsNumeric`. – phoog Mar 21 '12 at 17:30
  • 3
    I like the approach to check the data type first, but I suggest to modify the second part of the code by using `Double tmp; var isSuccess=Double.TryParse(Expression as string, out tmp); return isSuccess;` instead of the surrounding try-catch block. – Matt Apr 02 '14 at 11:09
8

There's the TryParse method, which returns a bool indicating if the conversion was successful.

Corey
  • 1,177
  • 4
  • 16
  • 24
6

Other answers have suggested using TryParse, which might fit your needs, but the safest way to provide the functionality of the IsNumeric function is to reference the VB library and use the IsNumeric function.

IsNumeric is more flexible than TryParse. For example, IsNumeric returns true for the string "$100", while the TryParse methods all return false.

To use IsNumeric in C#, add a reference to Microsoft.VisualBasic.dll. The function is a static method of the Microsoft.VisualBasic.Information class, so assuming you have using Microsoft.VisualBasic;, you can do this:

if (Information.IsNumeric(txtMyText.Text.Trim())) //...
phoog
  • 42,068
  • 6
  • 79
  • 117
  • 7
    I'm not sure I would want the result "true" for `"$100"` being numeric?! – cederlof Aug 13 '14 at 09:06
  • 4
    @cederlof I'm not sure you would, either, unless you are trying to replicate Visual Basic's `IsNumeric` function, which is mentioned in the question. That function returns true for "$100". If you were trying to reproduce the behavior of an Excel VBA procedure, for example, you would therefore want the function to return true for "$100" and you would likely be better off using Microsoft.VisualBasic.dll than trying to write your own replacement function. – phoog Aug 18 '14 at 20:31
1

You should use TryParse method which Converts the string representation of a number to its 32-bit signed integer equivalent. A return value indicates whether the conversion succeeded.

    int intParsed;
    if(int.TryParse(txtMyText.Text.Trim(),out intParsed))
    {
        // perform your code
    }
DotNetUser
  • 6,494
  • 1
  • 25
  • 27
  • `int.TryParse` returns false for `"$100"` and `"1E2"`, while `IsNumeric` returns true. – phoog Mar 21 '12 at 17:35
  • You could use a overloaded Int32.TryParse Method (String, NumberStyles, IFormatProvider, Int32%) to specify currency or exponent. http://msdn.microsoft.com/en-us/library/zf50za27(v=vs.90).aspx – DotNetUser Mar 21 '12 at 17:58
1

There's a slightly better way:

int valueParsed;
if(Int32.TryParse(txtMyText.Text.Trim(), out valueParsed))
{ ... }

If you try to parse the text and it can't be parsed, the Int32.Parse method will raise an exception. I think it is better for you to use the TryParse method which will capture the exception and let you know as a boolean if any exception was encountered.

There are lot of complications in parsing text which Int32.Parse takes into account. It is foolish to duplicate the effort. As such, this is very likely the approach taken by VB's IsNumeric. You can also customize the parsing rules through the NumberStyles enumeration to allow hex, decimal, currency, and a few other styles.

Another common approach for non-web based applications is to restrict the input of the text box to only accept characters which would be parseable into an integer.

EDIT: You can accept a larger variety of input formats, such as money values ("$100") and exponents ("1E4"), by specifying the specific NumberStyles:

int valueParsed;
if(Int32.TryParse(txtMyText.Text.Trim(), NumberStyles.AllowCurrencySymbol | NumberStyles.AllowExponent, CultureInfo.CurrentCulture, out valueParsed))
{ ... }

... or by allowing any kind of supported formatting:

int valueParsed;
if(Int32.TryParse(txtMyText.Text.Trim(), NumberStyles.Any, CultureInfo.CurrentCulture, out valueParsed))
{ ... }
Scott
  • 1,876
  • 17
  • 13
  • `IsNumeric` returns `true` for strings like `"1E2"` and `"$100"`, while `Int32.TryParse` returns false for those strings. – phoog Mar 21 '12 at 17:34
  • 1
    @phoog the default behavior is to not support scientific notiation or money values. you can adjust the behavior by passing in a combination of NumberStyles options, such as: Int32.TryParse("1E2", NumberStyles.AllowCurrencySymbol | NumberStyles.AllowExponent, CultureInfo.CurrentCulture, out valueParsed). You can also specify NumberStyles.Any, which is likely what VB's IsNumeric does behind the scenes. – Scott Mar 21 '12 at 17:41
  • 1
    of course, but if I had a requirement to duplicate the functionality of `IsNumeric` in a C# project, I'd just call `IsNumeric` rather than writing new C# code and attempting to make sure I've covered all the corner cases correctly. – phoog Mar 21 '12 at 17:44