代码之家  ›  专栏  ›  技术社区  ›  Piotr Czapla

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

  •  76
  • Piotr Czapla  · 技术社区  · 15 年前

    我想检查一个物体是否是数字,这样 .ToString() 将导致包含数字和 + , - , .

    是否可以通过简单的类型签入.NET(例如: if (p is Number) )?

    还是应该转换为字符串,然后尝试解析为double?

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

    <string>content</string>
    

    <numeric>123.3</numeric>
    

    或者提出例外。

    10 回复  |  直到 6 年前
        1
  •  150
  •   Matthew Layton    12 年前

    您只需要对每个基本的数字类型进行类型检查。

    下面是一个扩展方法,它应该完成以下工作:

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

    这应该包括所有的数字类型。

    更新

    似乎您确实想在反序列化过程中解析字符串中的数字。在这种情况下,最好使用 double.TryParse .

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

    当然,这不会处理非常大的整数/长小数,但是如果是这种情况,您只需要添加额外的调用 long.TryParse / decimal.TryParse /不管其他什么。

        2
  •  34
  •   Noctis    6 年前

    取自 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);
    }
    
        3
  •  18
  •   Fabrício Matté    10 年前

    利用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()框的值类型以来,泛型已被删除。还包括对可以为空值的修复。

        4
  •  9
  •   Mick Bruno    10 年前

    上面有一些很好的答案。这是一个综合解决方案。三种不同情况下的过载。

    // 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)); }
    
        5
  •  7
  •   satnhak    10 年前

    判断内置类型是否为数字的最可靠方法可能是引用,而不是自己滚动。 Microsoft.VisualBasic 并打电话 Information.IsNumeric(object value) . 该实现处理许多细微的情况,例如 char[] 以及十六进制和OCT字符串。

        6
  •  3
  •   Marc Gravell    15 年前

    这里有三个不同的概念:

    • 检查它是否 一个数字(即(通常是装箱的)数值本身),用 is -例如 if(obj is int) {...}
    • 检查字符串是否可以被解析为数字;使用 TryParse()
    • 但如果对象不是数字或字符串,但您怀疑 ToString() 可能会给你一些 就像一个数字,那么 呼叫 托斯特林() 把它当作一根绳子

    在前两种情况下,您可能需要分别处理希望支持的每种数字类型。( double / decimal / int )-例如,每个都有不同的范围和精度。

    您也可以查看regex进行快速粗略检查。

        7
  •  3
  •   Philippe Leybaert    15 年前

    假设您的输入是字符串…

    有两种方法:

    使用double.typarse()。

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

    使用正则表达式

     bool isNumber = Regex.IsMatch(input,@"-?\d+(\.\d+)?");
    
        8
  •  2
  •   Martin Liversage    6 年前

    您可以使用这样的代码:

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

    如果你的对象是 Int32 , Single , Double 它将执行转换。此外,字符串实现 IConvertible 但如果绳子不能转换成双股,那么 FormatException 将被抛出。

        9
  •  1
  •   Peter Lillevold Rene    15 年前

    是的,这是可行的:

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

    对于浮点数,必须使用浮点类型进行测试:

    object x = 1f;
    Assert.That(x is float);
    
        10
  •  1
  •   to StackOverflow    15 年前

    如果你的要求是真的

    .ToString()将生成一个字符串 包含数字和+、-、。

    如果你想使用double.typarse,那么你需要使用一个带numberStyles参数的重载,并确保你使用的是不变的区域性。

    例如,对于可能具有前导符号、无前导或尾随空格、无千位分隔符和句点小数分隔符的数字,请使用:

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