Here I saw an example:

public static bool IsNumeric(object Expression) { double retNum; bool isNum = Double.TryParse(Convert.ToString(Expression), System.Globalization.NumberStyles.Any,System.Globalization.NumberFormatInfo.InvariantInfo, out retNum ); return isNum; } 

But using it I often get this error:

column "nan" does not exist

Those. NaN he considers number.

And about the decimal separator: this, as I understand it, depends on the locale settings, and somewhere this is a period, and somewhere else is a comma?

What is the guaranteed way to check if it is a number or not?

  • GetType () not suitable? - Dmitry
  • I get the data as a string - des1roer
  • Corrected the answer - Dmitry

4 answers 4

nan he counts as a number

is that bad? You can add a banal check.

 public static bool IsNumeric(object Expression) { double retNum; bool isNum = Double.TryParse(Convert.ToString(Expression), System.Globalization.NumberStyles.Any,System.Globalization.NumberFormatInfo.InvariantInfo, out retNum ); if (isNum) { isNum = !(new double[] {double.PositiveInfinity, double.NegativeInfinity, double.NaN}).Contains(retNum); } return isNum; } 

As for the separator, I can not offer anything smarter than

 bool isNum = Double.TryParse(Convert.ToString(Expression).Replace(',','.'), System.Globalization.NumberStyles.Any,System.Globalization.NumberFormatInfo.InvariantInfo, out retNum ); 
  • 2
    delimiter can happen trouble in different locales, for this purpose it is used: System.Globalization.NumberStyles.Any, System.Globalization.NumberFormatInfo.InvariantInfo - Dmitry
  • @Dmitry, but what's the trouble? - 4per
  • one
    Well, for what purpose do you replace the comma with a period? if we already use any possible separators? - Dmitry
  • @Dmitry, Double.Parse (Convert.ToString ("12.7"), System.Globalization.NumberStyles.Any, System.Globalization.NumberFormatInfo.InvariantInfo) returns me 127 - 4per
  • Well, yes, you probably should use System.Globalization.NumberStyles.AllowDecimalPoint, System.Globalization.NumberFormatInfo.Invaβ€Œβ€‹riantInfo - Dmitry

Try the following method:

 public static bool IsNumeric(object expression) { if (expression == null) return false; switch (Type.GetTypeCode(expression.GetType())) { case TypeCode.Byte: case TypeCode.SByte: case TypeCode.UInt16: case TypeCode.UInt32: case TypeCode.UInt64: case TypeCode.Int16: case TypeCode.Int32: case TypeCode.Int64: case TypeCode.Decimal: case TypeCode.Double: case TypeCode.Single: case TypeCode.Char: return true; } string exprStr = Convert.ToString(expression); double doubleNum; return (Double.TryParse(exprStr, NumberStyles.Any, NumberFormatInfo.CurrentInfo, out doubleNum) || Double.TryParse(exprStr, NumberStyles.Any, NumberFormatInfo.InvariantInfo, out doubleNum)) && !Double.IsNaN(doubleNum) && !Double.IsInfinity(doubleNum); } 

Advantages of the approach:

  • The numbers specified by the string are correctly perceived, both in the current and in the neutral locale. With reference to the Russian locale, this means that decimal separators are perceived as . (dot), and , (comma).
  • The value of the null argument is correctly processed.
  • As indicated in the question text, the numbers Double.NaN , Double.PositiveInfinity and Double.NegativeInfinity are not counted as numbers. For them, the method returns false .

Generally speaking, if you need such a check, then it is likely that there is something wrong with the application architecture. It is usually required to check whether an object is an instance of a particular type. Without reduction to a specific type, with rare exceptions, there is not much sense in working with an object.

  • I thought that I would have to go through the mapped localizations manually. - 4per

can be so:

 public static bool IsNumeric(this object Expression) { var retType = Expression.GetType(); if(retType == typeof(string)) { double d = 0; return Expression != null && double.TryParse(Expression.ToString(), System.Globalization.NumberStyles.Any, System.Globalization.NumberFormatInfo.InvariantInfo, out d); } // ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΡΡ‚Ρ€ΠΎΠΈΡ‚ΡŒ ΠΊΠΎΠ½ΡΡ‚Ρ€ΡƒΠΊΡ†ΠΈΡŽ со всСми числовыми Ρ‚ΠΈΠΏΠ°ΠΌΠΈ // Ρ‚Π°ΠΊ ΠΌΡ‹ Π³Π°Ρ€Π°Π½Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½ΠΎ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΠΌ число Π»ΠΈ это. var isNum = retType == typeof(int) || retType == typeof(long); if(isNum) return isNum; } 

UPD: in this version is used extensions

  • You have a compilation error - Pavel Mayorov
 try { object sumUbit; float q = float.Parse(sumUbit.toString); } catch { MessageBox.Show("НС число","Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅"); } 

and if not, then I did not understand the question.

  • one
    This is not an answer, let alone syntax errors and the existing TryParse overload, which allows to avoid exceptions. - Align
  • @Align may be an answer with errors or not the best solution. But why not an answer at all? - Nick Volynkin ♦
  • @NickVolynkin because nothing significant has been changed from the code from the question - Pavel Mayorov