检查一个对象是否是C#中的一个数字
我想检查一个对象是否是一个数字,以便.ToString()
将导致包含数字和+
, -
,的string.
是否可以通过在.net中简单的types检查(如: if (p is Number)
)?
或者我应该转换为string,然后尝试parsing加倍?
更新:澄清我的对象是int,uint,float,double等等,它不是一个string。 我想做一个函数,将任何对象序列化到XML如下所示:
<string>content</string>
要么
<numeric>123.3</numeric>
或引发exception。
您只需要对每种基本数字types进行types检查。
这是一个应该完成这个工作的扩展方法:
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; }
这应该涵盖所有的数字types。
更新
看来你确实想在反序列化过程中parsingstring中的数字。 在这种情况下,最好使用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
/其他任何。
来自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); }
利用IsPrimitive属性来创build一个方便的扩展方法:
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); }
编辑:根据意见修正。 generics被删除,因为.GetType()框的值types。 还包括修复空值。
上面有一些很好的答案。 这是一个全方位的解决scheme。 针对不同情况的三种重载。
// 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)); }
而不是滚动自己的,最可靠的方式来告诉如果内置types是数字可能是引用Microsoft.VisualBasic
并调用Information.IsNumeric(object value)
。 该实现处理了一些细微的情况,如char[]
和HEX和OCTstring。
这里有三个不同的概念:
- 检查它是否是一个数字(即一个(通常是盒装)数值本身),用
is
检查types – 例如if(obj is int) {...}
- 检查一个string是否可以被parsing为一个数字; 使用
TryParse()
- 但是如果对象不是数字或string,但是您怀疑
ToString()
可能会给出类似于数字的东西,则调用ToString()
并将其视为string
在前两种情况下,您可能需要分别处理您想要支持的每个数字types( double
/ decimal
/ int
) – 例如,每个数字都有不同的范围和精度。
你也可以看看正则expression式快速粗略的检查。
假设你的input是一个string…
有两种方法:
使用Double.TryParse()
double temp; bool isNumber = Double.TryParse(input, out temp);
使用正则expression式
bool isNumber = Regex.IsMatch(input,@"-?\d+(\.\d+)?");
是的,这工作:
object x = 1; Assert.That(x is int);
对于浮点数,你将不得不使用floattypes进行testing:
object x = 1f; Assert.That(x is float);
你可以使用这样的代码:
if (n is IConvertible) return ((IConvertible) n).ToDouble(CultureInfo.CurrentCulture); else // Cannot be converted.
如果你的对象是一个string,这将不会parsingstring。 但是,如果您的对象是Int32,Single,Double等,它将执行转换。
如果你的要求是真的
.ToString()会产生一个包含数字和+, – ,的string。
你想使用double.TryParse,那么你需要使用带有NumberStyles参数的重载,并确保你使用的是不变的文化。
例如,对于可能具有前导符号的数字,没有前导或尾随空白,没有千位分隔符和句点小数点分隔符,请使用:
NumberStyles style = NumberStyles.AllowLeadingSign | NumberStyles.AllowDecimalPoint | double.TryParse(input, style, CultureInfo.InvariantCulture, out result);