Проверка, является ли объект числом в C#

На самом деле я хотел добавить это как комментарий, но не мог украсить его легко, поэтому добавлял как ответ, пожалуйста, не рассматривайте это как ответ.

Это то, что я сделал, чтобы понять -

выполнять следующие один за другим и понимать вывод на каждом шаге

a = [1,2]
b = [1,2,3]
b.pop()
id(a)
id(b)
a is b
a == b
82
задан Owen Blacker 28 February 2012 в 22:12
поделиться

8 ответов

You will simply need to do a type check for each of the basic numeric types.

Here's an extension method that should do the job:

public static bool IsNumber(this object value)
{
    return value is sbyte
            || value is byte
            || value is short
            || value is ushort
            || value is int
            || value is uint
            || value is long
            || value is ulong
            || value is float
            || value is double
            || value is decimal;
}

This should cover all numeric types.

Update

It seems you do actually want to parse the number from a string during deserialisation. In this case, it would probably just be best to use double.TryParse.

string value = "123.3";
double num;
if (!double.TryParse(value, out num))
    throw new InvalidOperationException("Value is not a number.");

Of course, this wouldn't handle very large integers/long decimals, but if that is the case you just need to add additional calls to long.TryParse / decimal.TryParse / whatever else.

168
ответ дан 24 November 2019 в 09:02
поделиться

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);
}
36
ответ дан 24 November 2019 в 09:02
поделиться

Воспользуйтесь преимуществом свойства IsPrimitive, чтобы создать удобный метод расширения:

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);
}

РЕДАКТИРОВАТЬ: Исправлено согласно комментариям. Дженерики были удалены, поскольку типы значений .GetType (). Также включено исправление для значений, допускающих значение NULL.

19
ответ дан 24 November 2019 в 09:02
поделиться

Здесь есть три различных понятия:

  • , чтобы проверить, число (т.е. само числовое значение (обычно заключенное в рамку)), проверьте тип с помощью равно - например, if (obj is int) {...}
  • , чтобы проверить, может ли строка быть проанализирована как число; используйте TryParse ()
  • , но если объект не является числом или строкой, но вы подозреваете, что ToString () может дать что-то, что выглядит как число, затем вызовите ToString () и обработайте его как строку

В обоих первых двух случаях вам, вероятно, придется обрабатывать отдельно каждый числовой тип, который вы хотите поддерживать ( double / decimal / int ) - например, каждый из них имеет разные диапазоны и точность.

4
ответ дан 24 November 2019 в 09:02
поделиться

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+)?");
4
ответ дан 24 November 2019 в 09:02
поделиться

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.

2
ответ дан 24 November 2019 в 09:02
поделиться

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);
1
ответ дан 24 November 2019 в 09:02
поделиться

Если ваше требование действительно

.ToString () приведет к строке содержащие цифры и +, - ,.

, и вы хотите использовать double.TryParse, тогда вам нужно использовать перегрузку, которая принимает параметр NumberStyles, и убедитесь, что вы используете инвариантный язык и региональные параметры.

Например, для числа, которое может иметь начальный знак, без начальных или конечных пробелов, без разделителя тысяч и десятичного разделителя с точкой, используйте:

NumberStyles style = 
   NumberStyles.AllowLeadingSign | 
   NumberStyles.AllowDecimalPoint | 
double.TryParse(input, style, CultureInfo.InvariantCulture, out result);
1
ответ дан 24 November 2019 в 09:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: