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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1130698/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 08:56:18  来源:igfitidea点击:

Checking if an object is a number in C#

c#.netserializationxml-serialization

提问by Piotr Czapla

I'd like to check if an object is a number so that .ToString()would result in a string containing digits and +,-,.

我想检查一个对象是否是一个数字,以便.ToString()产生一个包含数字和+,的字符串-.

Is it possible by simple type checking in .net (like: if (p is Number))?

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

Or Should I convert to string, then try parsing to double?

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

Update:To clarify my object is int, uint, float, double, and so on it isn't a string. I'm trying to make a function that would serialize any object to xml like this:

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

<string>content</string>

or

或者

<numeric>123.3</numeric>

or raise an exception.

或引发异常。

采纳答案by Noldorin

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.

看来您确实想在反序列化期间解析字符串中的数字。在这种情况下,最好使用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.

当然,这不会处理非常大的整数/长小数,但如果是这样的话,你只需要额外的呼叫添加到long.TryParse/ decimal.TryParse/任何其他。

回答by Peter Lillevold

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:

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

object x = 1f;
Assert.That(x is float);

回答by Philippe Leybaert

Assuming your input is a string...

假设您的输入是一个字符串...

There are 2 ways:

有2种方式:

use Double.TryParse()

使用 Double.TryParse()

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

use Regex

使用正则表达式

 bool isNumber = Regex.IsMatch(input,@"-?\d+(\.\d+)?");

回答by Martin Liversage

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, Doubleetc. it will perform the conversion. Also, a string implements IConvertiblebut if the string isn't convertible to a double then a FormatExceptionwill be thrown.

如果你的对象是Int32SingleDouble等它执行转换。此外,一个字符串实现,IConvertible但如果该字符串不能转换为双精度那么 aFormatException将被抛出。

回答by Marc Gravell

There are three different concepts there:

这里有三个不同的概念:

  • to check if it isa number (i.e. a (typically boxed) numeric value itself), check the type with is- for example if(obj is int) {...}
  • to check if a string could be parsed as a number; use TryParse()
  • but if the object isn't a number or a string, but you suspect ToString()might give something that lookslike a number, then callToString()and treat it as a string
  • 要检查它是否是数字(即(通常是装箱的)数值本身),请检查类型is- 例如if(obj is int) {...}
  • 检查字符串是否可以解析为数字;用TryParse()
  • 但是如果对象不是数字或字符串,但您怀疑ToString()可能给出看起来像数字的东西,则调用ToString()并将其视为字符串

In both the first two cases, you'll probably have to handle separately each numeric type you want to support (double/decimal/int) - each have different ranges and accuracy, for example.

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

You could also look at regex for a quick rough check.

您还可以查看正则表达式进行快速粗略检查。

回答by Saul Dolgin

Taken from Scott Hanselman's Blog:

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

回答by Kenan E. K.

Take advantage of the IsPrimitive property to make a handy extension method:

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

EDIT: Fixed as per comments. The generics were removed since .GetType() boxes value types. Also included fix for nullable values.

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

回答by Joe

If your requirement is really

如果您的要求是真的

.ToString() would result in a string containing digits and +,-,.

.ToString() 将产生一个包含数字和 +,-, 的字符串。

and you want to use double.TryParse then you need to use the overload that takes a NumberStyles parameter, and make sure you are using the invariant culture.

并且您想使用 double.TryParse 那么您需要使用带 NumberStyles 参数的重载,并确保您使用的是不变区域性。

For example for a number which may have a leading sign, no leading or trailing whitespace, no thousands separator and a period decimal separator, use:

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

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

回答by Mick Bruno

There are some great answers above. Here is an all-in-one solution. Three overloads for different circumstances.

上面有一些很好的答案。这是一个多合一的解决方案。针对不同情况的三种重载。

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

回答by satnhak

Rather than rolling your own, the most reliable way to tell if an in-built type is numeric is probably to reference Microsoft.VisualBasicand call Information.IsNumeric(object value). The implementation handles a number of subtle cases such as char[]and HEX and OCT strings.

判断内置类型是否为数字的最可靠方法可能是引用Microsoft.VisualBasic和调用Information.IsNumeric(object value). 该实现处理了许多微妙的情况,例如char[]HEX 和 OCT 字符串。