检查对象是否是C#中的数字

Pio*_*pla 82 .net c# serialization xml-serialization

我想检查的对象是一个数字,这样.ToString()会导致包含数字和字符串+,-,.

是否可以通过简单的类型检查.net(如:)if (p is Number)

或者我应该转换为字符串,然后尝试解析加倍?

更新:澄清我的对象是int,uint,float,double等等它不是一个字符串.我正在尝试创建一个将任何对象序列化为xml的函数,如下所示:

<string>content</string>
Run Code Online (Sandbox Code Playgroud)

要么

<numeric>123.3</numeric>
Run Code Online (Sandbox Code Playgroud)

或提出例外.

Nol*_*rin 168

您只需要对每种基本数字类型进行类型检查.

这是一个应该完成工作的扩展方法:

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;
}
Run Code Online (Sandbox Code Playgroud)

这应该涵盖所有数字类型.

更新

看起来你确实想在反序列化期间解析字符串中的数字.在这种情况下,它可能只是最好使用double.TryParse.

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

当然,这不会处理非常大的整数/长小数,但如果是这种情况,你只需要添加额外的调用long.TryParse/ decimal.TryParse/其他任何东西.


Sau*_*gin 36

摘自Scott Hanselman的博客:

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);
}
Run Code Online (Sandbox Code Playgroud)

  • 这种方法的问题是如果你传入一个看起来像数字的字符串,它将格式化它.可能对大多数人来说都不错,但它对我来说是个绝佳的噱头. (6认同)
  • 另一个潜在的问题是您无法解析 double 的最小/最大值。`double.Parse(double.MaxValue.ToString())` 会导致 `OverflowException`。在这种情况下,您可以通过提供往返修饰符 `.ToString("R")` 来解决此问题,但该重载不适用于 `Convert.ToString(...)`,因为我们不知道类型。我知道这是一个边缘案例,但我在为自己的“.IsNumeric()”扩展编写测试时偶然发现了它。我的“解决方案”是在尝试解析任何内容之前添加一个类型检查开关,请参阅我对此问题的回答以获取代码。 (2认同)

Ken*_* K. 19

利用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);
}
Run Code Online (Sandbox Code Playgroud)

编辑:根据评论固定.由于.GetType()框值类型,因此删除了泛型.还包括修复可空值.


Mic*_*uno 9

上面有一些很好的答案.这是一个多功能的解决方案.针对不同情况的三次重载.

// 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)); }
Run Code Online (Sandbox Code Playgroud)

  • 我认为可以用null值来调用它.object obj = null; obj.IsNumeric(); (5认同)

bri*_*ler 7

而不是滚动自己,最可靠的方式来判断内置类型是否为数字可能是引用Microsoft.VisualBasic和调用Information.IsNumeric(object value).该实现处理许多细微的情况,例如char[]HEX和OCT字符串.


Mar*_*age 6

你可以使用这样的代码:

if (n is IConvertible)
  return ((IConvertible) n).ToDouble(CultureInfo.CurrentCulture);
else
  // Cannot be converted.
Run Code Online (Sandbox Code Playgroud)

如果您的对象是Int32、等SingleDouble它将执行转换。另外,字符串可以实现IConvertible,但如果字符串不能转换为双精度型,则将FormatException抛出 a 。