What is the C# equivalent of NaN or IsNumeric?

C#Parsing

C# Problem Overview


What is the most efficient way of testing an input string whether it contains a numeric value (or conversely Not A Number)? I guess I can use Double.Parse or a regex (see below) but I was wondering if there is some built in way to do this, such as javascript's NaN() or IsNumeric() (was that VB, I can't remember?).

public static bool IsNumeric(this string value)
{
    return Regex.IsMatch(value, "^\\d+$");
}

C# Solutions


Solution 1 - C#

This doesn't have the regex overhead

double myNum = 0;
String testVar = "Not A Number";

if (Double.TryParse(testVar, out myNum)) {
  // it is a number
} else {
  // it is not a number
}

Incidentally, all of the standard data types, with the glaring exception of GUIDs, support TryParse.

update
secretwep brought up that the value "2345," will pass the above test as a number. However, if you need to ensure that all of the characters within the string are digits, then another approach should be taken.

example 1:

public Boolean IsNumber(String s) {
  Boolean value = true;
  foreach(Char c in s.ToCharArray()) {
    value = value && Char.IsDigit(c);
  }

  return value;
}

or if you want to be a little more fancy

public Boolean IsNumber(String value) {
  return value.All(Char.IsDigit);
}

update 2 ( from @stackonfire to deal with null or empty strings)

public Boolean IsNumber(String s) { 
	Boolean value = true; 
	if (s == String.Empty || s == null) { 
		value=false; 
	} else { 
		foreach(Char c in s.ToCharArray()) { 
			value = value && Char.IsDigit(c); 
		} 
	} return value; 
}

Solution 2 - C#

I prefer something like this, it lets you decide what NumberStyle to test for.

public static Boolean IsNumeric(String input, NumberStyles numberStyle) {
    Double temp;
    Boolean result = Double.TryParse(input, numberStyle, CultureInfo.CurrentCulture, out temp);
    return result;
}

Solution 3 - C#

In addition to the previous correct answers it is probably worth pointing out that "Not a Number" (NaN) in its general usage is not equivalent to a string that cannot be evaluated as a numeric value. NaN is usually understood as a numeric value used to represent the result of an "impossible" calculation - where the result is undefined. In this respect I would say the Javascript usage is slightly misleading. In C# NaN is defined as a property of the single and double numeric types and is used to refer explicitly to the result of diving zero by zero. Other languages use it to represent different "impossible" values.

Solution 4 - C#

I know this has been answered in many different ways, with extensions and lambda examples, but a combination of both for the simplest solution.

public static bool IsNumeric(this String s)
{
    return s.All(Char.IsDigit);
}

or if you are using Visual Studio 2015 (C# 6.0 or greater) then

public static bool IsNumeric(this String s) => s.All(Char.IsDigit);

Awesome C#6 on one line. Of course this is limited because it just tests for only numeric characters.

To use, just have a string and call the method on it, such as:

bool IsaNumber = "123456".IsNumeric();

Solution 5 - C#

Yeah, IsNumeric is VB. Usually people use the TryParse() method, though it is a bit clunky. As you suggested, you can always write your own.

int i;
if (int.TryParse(string, out i))
{

}

Solution 6 - C#

I like the extension method, but don't like throwing exceptions if possible. I opted for an extension method taking the best of 2 answers here.

    /// <summary>
    /// Extension method that works out if a string is numeric or not
    /// </summary>
    /// <param name="str">string that may be a number</param>
    /// <returns>true if numeric, false if not</returns>
    public static bool IsNumeric(this String str)
    {
        double myNum = 0;
        if (Double.TryParse(str, out myNum))
        {
            return true;
        }
        return false;
    }

Solution 7 - C#

VB has the IsNumeric function. You could reference Microsoft.VisualBasic.dll and use it.

Solution 8 - C#

Simple extension:

public static bool IsNumeric(this String str)
{
	try
	{
		Double.Parse(str.ToString());
		return true;
	}
	catch {
	}
	return false;
}

Solution 9 - C#

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!

Solution 10 - C#

public static bool IsNumeric(string anyString)
{
	if (anyString == null)
	{
	    anyString = "";
	}

	if (anyString.Length > 0)
	{
	    double dummyOut = new double();
	    System.Globalization.CultureInfo cultureInfo = new System.Globalization.CultureInfo("en-US", true);
	    return Double.TryParse(anyString, System.Globalization.NumberStyles.Any, cultureInfo.NumberFormat, out dummyOut);
	}
	else
	{
	    return false;
	}
}

Solution 11 - C#

Maybe this is a C# 3 feature, but you could use double.NaN.

Solution 12 - C#

Actually, Double.NaN is supported in all .NET versions 2.0 and greater.

Solution 13 - C#

I was using Chris Lively's snippet (selected answer) encapsulated in a bool function like Gishu's suggestion for a year or two. I used it to make sure certain query strings were only numeric before proceeding with further processing. I started getting some errant querystrings that the marked answer was not handling, specifically, whenever a comma was passed after a number like "3645," (returned true). This is the resulting mod:

   static public bool IsNumeric(string s)
   {
      double myNum = 0;
      if (Double.TryParse(s, out myNum))
      {
         if (s.Contains(",")) return false;
         return true;
      }
      else
      {
         return false;
      }
   }

Solution 14 - C#

I have a slightly different version which returns the number. I would guess that in most cases after testing the string you would want to use the number.

public bool IsNumeric(string numericString, out Double numericValue)
{
    if (Double.TryParse(numericString, out numericValue))
        return true;
    else
        return false;
}

Solution 15 - C#

This is a modified version of the solution proposed by Mr Siir. I find that adding an extension method is the best solution for reuse and simplicity in the calling method.

public static bool IsNumeric(this String s)
{
    try { double.Parse(s); return true; }
    catch (Exception) { return false; }
}

I modified the method body to fit on 2 lines and removed the unnecessary .ToString() implementation. For those not familiar with extension methods here is how to implement:

Create a class file called ExtensionMethods. Paste in this code:

using System;
using System.Collections.Generic;
using System.Text;

namespace YourNameSpaceHere
{
    public static class ExtensionMethods
    {
        public static bool IsNumeric(this String s)
        {
            try { double.Parse(s); return true; }
            catch (Exception) { return false; }
        }
    }
}

Replace YourNameSpaceHere with your actual NameSpace. Save changes. Now you can use the extension method anywhere in your app:

bool validInput = stringVariable.IsNumeric();

Note: this method will return true for integers and decimals, but will return false if the string contains a comma. If you want to accept input with commas or symbols like "$" I would suggest implementing a method to remove those characters first then test if IsNumeric.

Solution 16 - C#

If you don't want the overhead of adding the Microsoft.VisualBasic library just for isNumeric, here's the code reverse engineered:

public bool IsNumeric(string s)
{
	if (s == null) return false;

	int state = 0; // state 0 = before number, state 1 = during number, state 2 = after number
	bool hasdigits = false;
	bool hasdollar = false;
	bool hasperiod = false;
	bool hasplusminus = false;
	bool hasparens = false;
	bool inparens = false;

	for (var i = 0; i <= s.Length - 1; i++)
	{
		switch (s[i])
		{
			case char n when (n >= '0' && n <= '9'):
					if (state == 2) return false; // no more numbers at the end (i.e. "1 2" is not valid)

					if (state == 0) state = 1; // begin number state
					hasdigits = true;
					break;

			case '-':
			case '+':
					// a plus/minus is allowed almost anywhere, but only one, and you cannot combine it with parenthesis
					if (hasplusminus || hasparens) return false;

					if (state == 1) state = 2; // exit number state (i.e. "1-" is valid but 1-1 is not)
					hasplusminus = true;
					break;

			case ' ':
			case '\t':
			case '\r':
			case '\n':
					// don't allow any spaces after parenthesis/plus/minus, unless there's a $
					if (state == 0 && (hasparens || (hasplusminus && !hasdollar))) return false;
					if (state == 1) state = 2; // exit number state
					break;

			case ',':
					// do not allow commas unless in the middle of the number, and not after a decimal
					if (state != 1 || hasperiod) return false;
					break;

			case '.':
					// only allow one period in the number
					if (hasperiod || state == 2) return false;

					if (state == 0) state = 1; // begin number state
					hasperiod = true;
					break;

			case '$':
					// dollar symbol allowed anywhere, but only one
					if (hasdollar) return false;

					if (state == 1) state = 2; // exit number state (i.e. "1$" is valid but "1$1" is not)
					hasdollar = true;
					break;

			case '(':
					// only allow one parens at the beginning, and cannot combine with plus/minus
					if (state != 0 || hasparens || hasplusminus) return false;
					hasparens = true;
					inparens = true;
					break;

			case ')':
					if (state == 1 && inparens) state = 2; // exit number state
					if (state != 2 || !inparens) return false; // invalid end parens
					inparens = false; // end parens mode
					break;

			default:
					// oh oh, we hit a bad character
					return false;
		}
	}

	// must have at leats one digit, and cannot have imbalanced parenthesis
	if (!hasdigits || inparens) return false;

	// if we got all the way to here...
	return true;
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionjohncView Question on Stackoverflow
Solution 1 - C#NotMeView Answer on Stackoverflow
Solution 2 - C#Anthony MastreanView Answer on Stackoverflow
Solution 3 - C#Stu MackellarView Answer on Stackoverflow
Solution 4 - C#Paul BartlettView Answer on Stackoverflow
Solution 5 - C#Ed S.View Answer on Stackoverflow
Solution 6 - C#NER1808View Answer on Stackoverflow
Solution 7 - C#shahkalpeshView Answer on Stackoverflow
Solution 8 - C#MrSiirView Answer on Stackoverflow
Solution 9 - C#VincyView Answer on Stackoverflow
Solution 10 - C#MnaouarView Answer on Stackoverflow
Solution 11 - C#kennyView Answer on Stackoverflow
Solution 12 - C#MadcatView Answer on Stackoverflow
Solution 13 - C#secretwepView Answer on Stackoverflow
Solution 14 - C#Keith AymarView Answer on Stackoverflow
Solution 15 - C#SendETHToThisAddressView Answer on Stackoverflow
Solution 16 - C#Brain2000View Answer on Stackoverflow