11

One thing that has bothered me about C# since its release was the lack of a generic IsNumeric function. I know it is difficult to generate a one-stop solution to detrmine if a value is numeric.

I have used the following solution in the past, but it is not the best practice because I am generating an exception to determine if the value is IsNumeric:

public bool IsNumeric(string input)
{
    try
    {
        int.Parse(input);
        return true;
    }
    catch
    {
        return false;
    }
}

Is this still the best way to approach this problem or is there a more efficient way to determine if a value is numeric in C#?

Chris
  • 2,959
  • 1
  • 30
  • 46
Michael Kniskern
  • 24,792
  • 68
  • 164
  • 231
  • 1
    I'm wondering why you would check to see if a string can be converted to an int, but not hold on to and use the converted value? – jball May 26 '10 at 22:20
  • 1
    10 answers in six minutes. is this a c# only community ;) – Byron Whitlock May 26 '10 at 22:24
  • Char has IsDigit and IsNumber if that helps. It's definitely not elegant, but you could check each character if you wanted an alternative to Parse and TryParse. – Brandi May 26 '10 at 22:28
  • 2
    I think that you are just missing IsNumeric because you are used to using it. Usually one wants to use the numeric value for something if the string contains one, so using IsNumeric to find that out means that you will be parsing the string twice. It's better to use a method like `Int32.TryParse` that will both determine it the string contains a number and parse it in one operation. – Guffa May 26 '10 at 22:35

13 Answers13

22

Try this:

int temp;
return int.TryParse(input, out temp);

Of course, the behavior will be different from Visual Basic IsNumeric. If you want that behavior, you can add a reference to "Microsoft.VisualBasic" assembly and call the Microsoft.VisualBasic.Information.IsNumeric function directly.

Mehrdad Afshari
  • 414,610
  • 91
  • 852
  • 789
14

You can use extension methods to extend the String type to include IsInteger:

namespace ExtensionMethods
{
    public static class MyExtensions
    {
        public static bool IsInteger(this String input)
        {
             int temp;
             return int.TryParse(input, out temp);        
        }
    }   
}
Toji
  • 33,927
  • 22
  • 105
  • 115
Eric J.
  • 147,927
  • 63
  • 340
  • 553
9

Rather than using int.Parse, you can use int.TryParse and avoid the exception.

Something like this

public static bool IsNumeric(string input)
{
  int dummy;
  return int.TryParse(input, out dummy);
}

More generically you might want to look at double.TryParse.

One thing you should also consider is the potential of handling numeric string for different cultures. For example Greek (el-GR) uses , as a decimal separator while the UK (en-GB) uses a .. So the string "1,000" will either be 1000 or 1 depending on the current culture. Given this, you might consider providing overloads for IsNumeric that support passing the intended culture, number format etc. Take a look at the 2 overloads for double.TryParse.

Chris Taylor
  • 52,623
  • 10
  • 78
  • 89
5

I've used the following extension method before, if it helps at all:

public static int? AsNumeric(this string source)
{
  int result;
  return Int32.TryParse(source, out result) ? result : (int?)null;
}

Then you can use .HasValue for the bool you have now, or .Value for the value, but convert just once...just throwing it out there, not sure what situation you're using it for afterwards.

Nick Craver
  • 623,446
  • 136
  • 1,297
  • 1,155
  • 1
    Ha, typed an answer like this, just noticed you put up a more complete solution 3 minutes before me. I definitely question the discarding of a conversion result since it seems likely it will be needed soon if the string is numeric. – jball May 26 '10 at 22:29
4

If you use Int32.TryParse then you don't need to wrap the call in a TryCatch block, but otherwise, yes that is the approach to take.

jjnguy
  • 136,852
  • 53
  • 295
  • 323
Walter
  • 2,540
  • 2
  • 30
  • 38
3

Not exactly crazy about this approach, but you can just call the vb.net isNumeric function from C# by adding a reference to the Microsoft.VisualBasic.dll library...

bool x= Microsoft.VisualBasic.Information.IsNumeric("123");

The other approaches given are superior, but wanted to add this for the sake of completeness.

JohnFx
  • 34,542
  • 18
  • 104
  • 162
2

Lot's of TryParse answers. Here's something a bit different using Char.IsNumber():

    public bool IsNumeric(string s)
    {
        for (int i = 0; i < s.Length; i++)
        {
            if (char.IsNumber(s, i) == false)
            {
                return false;
            }
        }
        return true;
    }
Paul Kearney - pk
  • 5,435
  • 26
  • 28
1

I've been using the following small code snippet for years as a pure C# IsNumeric function.

Granted, it's not exactly the same as the Microsoft.VisualBasic library's IsNumeric function as that (if you look at the decompiled code) involves lots of type checking and usage of the IConvertible interface, however this small function has worked well for me.

Note also that this function uses double.TryParse rather than int.TryParse to allow both integer numbers (including long's) as well as floating point numbers to be parsed. Also note that this function specifically asserts an InvariantCulture when parsing (for example) floating point numbers, so will correctly identify both 123.00 and 123,00 (note the comma and decimal point separators) as floating point numbers.

using System;
using System.Globalization;

namespace MyNumberFunctions
{
   public static class NumberFunctions
   {
      public static bool IsNumeric(this object expression)
      {
         if (expression == null)
         {
            return false;
         }
         double number;
         return Double.TryParse(Convert.ToString(expression, CultureInfo.InvariantCulture), NumberStyles.Any, NumberFormatInfo.InvariantInfo, out number);
      }
   }
}

Usage is incredibly simple, since this is implemented as an extension method:

string myNumberToParse = "123.00";
bool isThisNumeric = myNumberToParse.IsNumeric();
CraigTP
  • 44,143
  • 8
  • 72
  • 99
1

Take a look on the following answer: What is the C# equivalent of NaN or IsNumeric?

Double.TryParse takes care of all numeric values and not only ints.

Community
  • 1
  • 1
Klinger
  • 4,900
  • 1
  • 30
  • 35
1

Another option - LINQ!

public static class StringExtensions
{
  public static bool IsDigits(this String text)
  {
    return !text.Any(c => !char.IsDigit(c));
  }
}

Note that this assumes you only want digits 0-9. If you want to accept decimal point, sign, exponent, etc, then repalce IsDigit() with IsNumber().

GeekyMonkey
  • 12,478
  • 6
  • 33
  • 39
0

You can still use the Visual Basic function in C#. The only thing you have to do is just follow my instructions shown below:

  1. Add the reference to the Visual Basic Library by right clicking on your project and selecting "Add Reference":

enter image description here

  1. Then import it in your class as shown below:

    using Microsoft.VisualBasic;

  2. Next use it wherever you want as shown below:

            if (!Information.IsNumeric(softwareVersion))
        {
            throw new DataException(string.Format("[{0}] is an invalid App Version!  Only numeric values are supported at this time.", softwareVersion));
        }
    

Hope, this helps and good luck!

Vincy
  • 1,078
  • 1
  • 9
  • 16
0
public bool IsNumeric(string input)
{
   int result;
   return Int32.TryParse(input,out result);
}
Alan
  • 45,915
  • 17
  • 113
  • 134
0

try this:

public static bool IsNumeric(object o)
{
    const NumberStyles sty = NumberStyles.Any;
    double d;
    return (o != null && Double.TryParse(o.ToString(), sty, null, out d));
}
Charles Bretana
  • 143,358
  • 22
  • 150
  • 216