[c#] Checking if an object is a number in C#

I'd like to check if an object is a number so that .ToString() would result in a string containing digits and +,-,.

Is it possible by simple type checking in .net (like: if (p is Number))?

Or Should I convert to string, then try parsing to double?

Update: To clarify my object is int, uint, float, double, and so on it isn't a string. I'm trying to make a function that would serialize any object to xml like this:

<string>content</string>

or

<numeric>123.3</numeric>

or raise an exception.

This question is related to c# .net serialization xml-serialization

The answer is


If your requirement is really

.ToString() would result in a string containing digits and +,-,.

and you want to use double.TryParse then you need to use the overload that takes a NumberStyles parameter, and make sure you are using the invariant culture.

For example for a number which may have a leading sign, no leading or trailing whitespace, no thousands separator and a period decimal separator, use:

NumberStyles style = 
   NumberStyles.AllowLeadingSign | 
   NumberStyles.AllowDecimalPoint | 
double.TryParse(input, style, CultureInfo.InvariantCulture, out result);

You could use code like this:

if (n is IConvertible)
  return ((IConvertible) n).ToDouble(CultureInfo.CurrentCulture);
else
  // Cannot be converted.

If your object is an Int32, Single, Double etc. it will perform the conversion. Also, a string implements IConvertible but if the string isn't convertible to a double then a FormatException will be thrown.


Rather than rolling your own, the most reliable way to tell if an in-built type is numeric is probably to reference Microsoft.VisualBasic and call Information.IsNumeric(object value). The implementation handles a number of subtle cases such as char[] and HEX and OCT strings.


Assuming your input is a string...

There are 2 ways:

use Double.TryParse()

double temp;
bool isNumber = Double.TryParse(input, out temp);

use Regex

 bool isNumber = Regex.IsMatch(input,@"-?\d+(\.\d+)?");

Taken from Scott Hanselman's Blog:

public static bool IsNumeric(object expression)
{
    if (expression == null)
    return false;

    double number;
    return Double.TryParse( Convert.ToString( expression
                                            , CultureInfo.InvariantCulture)
                          , System.Globalization.NumberStyles.Any
                          , NumberFormatInfo.InvariantInfo
                          , out number);
}

Yes, this works:

object x = 1;
Assert.That(x is int);

For a floating point number you would have to test using the float type:

object x = 1f;
Assert.That(x is float);

There are three different concepts there:

  • to check if it is a number (i.e. a (typically boxed) numeric value itself), check the type with is - for example if(obj is int) {...}
  • to check if a string could be parsed as a number; use TryParse()
  • but if the object isn't a number or a string, but you suspect ToString() might give something that looks like a number, then call ToString() and treat it as a string

In both the first two cases, you'll probably have to handle separately each numeric type you want to support (double/decimal/int) - each have different ranges and accuracy, for example.

You could also look at regex for a quick rough check.


There are some great answers above. Here is an all-in-one solution. Three overloads for different circumstances.

// Extension method, call for any object, eg "if (x.IsNumeric())..."
public static bool IsNumeric(this object x) { return (x==null ? false : IsNumeric(x.GetType())); }

// Method where you know the type of the object
public static bool IsNumeric(Type type) { return IsNumeric(type, Type.GetTypeCode(type)); }

// Method where you know the type and the type code of the object
public static bool IsNumeric(Type type, TypeCode typeCode) { return (typeCode == TypeCode.Decimal || (type.IsPrimitive && typeCode != TypeCode.Object && typeCode != TypeCode.Boolean && typeCode != TypeCode.Char)); }

While writing my own object.IsNumeric() extension method based on Saul Dolgin's answer to this question I ran into a potential issue in that you will get an OverflowException if you try it with double.MaxValue or double.MinValue.

My "solution" was to combine the accepted answer from Noldorin with the one from Saul Dolgin and add a pattern matching switch before trying to parse anything (and use some C#7 goodness to tidy up a bit):

public static bool IsNumeric(this object obj)
{
    if (obj == null) return false;

    switch (obj)
    {
        case sbyte _: return true;
        case byte _: return true;
        case short _: return true;
        case ushort _: return true;
        case int _: return true;
        case uint _: return true;
        case long _: return true;
        case ulong _: return true;
        case float _: return true;
        case double _: return true;
        case decimal _: return true;
    }

    string s = Convert.ToString(obj, CultureInfo.InvariantCulture);

    return double.TryParse(s, NumberStyles.Any, NumberFormatInfo.InvariantInfo, out double _);
}

Take advantage of the IsPrimitive property to make a handy extension method:

public static bool IsNumber(this object obj)
{
    if (Equals(obj, null))
    {
        return false;
    }

    Type objType = obj.GetType();
    objType = Nullable.GetUnderlyingType(objType) ?? objType;

    if (objType.IsPrimitive)
    {
        return objType != typeof(bool) && 
            objType != typeof(char) && 
            objType != typeof(IntPtr) && 
            objType != typeof(UIntPtr);
    }

    return objType == typeof(decimal);
}

EDIT: Fixed as per comments. The generics were removed since .GetType() boxes value types. Also included fix for nullable values.


Examples related to c#

How can I convert this one line of ActionScript to C#? Microsoft Advertising SDK doesn't deliverer ads How to use a global array in C#? How to correctly write async method? C# - insert values from file into two arrays Uploading into folder in FTP? Are these methods thread safe? dotnet ef not found in .NET Core 3 HTTP Error 500.30 - ANCM In-Process Start Failure Best way to "push" into C# array

Examples related to .net

You must add a reference to assembly 'netstandard, Version=2.0.0.0 How to use Bootstrap 4 in ASP.NET Core No authenticationScheme was specified, and there was no DefaultChallengeScheme found with default authentification and custom authorization .net Core 2.0 - Package was restored using .NetFramework 4.6.1 instead of target framework .netCore 2.0. The package may not be fully compatible Update .NET web service to use TLS 1.2 EF Core add-migration Build Failed What is the difference between .NET Core and .NET Standard Class Library project types? Visual Studio 2017 - Could not load file or assembly 'System.Runtime, Version=4.1.0.0' or one of its dependencies Nuget connection attempt failed "Unable to load the service index for source" Token based authentication in Web API without any user interface

Examples related to serialization

laravel Unable to prepare route ... for serialization. Uses Closure TypeError: Object of type 'bytes' is not JSON serializable Best way to save a trained model in PyTorch? Convert Dictionary to JSON in Swift Java: JSON -> Protobuf & back conversion Understanding passport serialize deserialize How to generate serial version UID in Intellij Parcelable encountered IOException writing serializable object getactivity() Task not serializable: java.io.NotSerializableException when calling function outside closure only on classes not objects Cannot deserialize the JSON array (e.g. [1,2,3]) into type ' ' because type requires JSON object (e.g. {"name":"value"}) to deserialize correctly

Examples related to xml-serialization

Serialize Property as Xml Attribute in Element Reading from memory stream to string There is an error in XML document (1, 41) Xml serialization - Hide null values Using DataContractSerializer to serialize, but can't deserialize back Serialize an object to XML Serializing an object as UTF-8 XML in .NET Convert XML String to Object Serialize an object to string Using StringWriter for XML Serialization