C# - 如何确定类型是否为数字
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1749966/
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
C# - how to determine whether a Type is a number
提问by Adi Barda
Is there a way to determine whether or not a given .Net Type is a number? For example: System.UInt32/UInt16/Doubleare all numbers. I want to avoid a long switch-case on the Type.FullName.
有没有办法确定给定的 .Net 类型是否是数字?例如:System.UInt32/UInt16/Double都是数字。我想避免在Type.FullName.
采纳答案by Philip Wallace
Try this:
尝试这个:
Type type = object.GetType();
bool isNumber = (type.IsPrimitiveImple && type != typeof(bool) && type != typeof(char));
Type type = object.GetType();
bool isNumber = (type.IsPrimitiveImple && type != typeof(bool) && type != typeof(char));
The primitive types are Boolean, Byte, SByte, Int16, UInt16, Int32, UInt32, Int64, UInt64, Char, Double,and Single.
基本类型是 Boolean、Byte、SByte、Int16、UInt16、Int32、UInt32、Int64、UInt64、Char、Double 和 Single。
Taking Guillaume's solutiona little further:
更进一步地考虑Guillaume 的解决方案:
public static bool IsNumericType(this object o)
{
switch (Type.GetTypeCode(o.GetType()))
{
case TypeCode.Byte:
case TypeCode.SByte:
case TypeCode.UInt16:
case TypeCode.UInt32:
case TypeCode.UInt64:
case TypeCode.Int16:
case TypeCode.Int32:
case TypeCode.Int64:
case TypeCode.Decimal:
case TypeCode.Double:
case TypeCode.Single:
return true;
default:
return false;
}
}
Usage:
用法:
int i = 32;
i.IsNumericType(); // True
string s = "Hello World";
s.IsNumericType(); // False
回答by Konamiman
You could use Type.IsPrimitiveand then sort out the Booleanand Chartypes, something like this:
您可以使用Type.IsPrimitive然后整理出Boolean和Char类型,如下所示:
bool IsNumeric(Type type)
{
return type.IsPrimitive && type!=typeof(char) && type!=typeof(bool);
}
EDIT: You may want to exclude the IntPtrand UIntPtrtypes as well, if you don't consider them to be numeric.
编辑:如果您不认为它们是数字,您可能还想排除IntPtr和UIntPtr类型。
回答by Darin Dimitrov
Unfortunately these types don't have much in common other than they are all value types. But to avoid a long switch-case you could just define a readonly list with all these types and then just check if the given type is inside the list.
不幸的是,除了它们都是值类型之外,这些类型没有太多共同点。但是为了避免长时间的 switch-case,你可以定义一个包含所有这些类型的只读列表,然后检查给定的类型是否在列表中。
回答by Jon Skeet
Don't use a switch - just use a set:
不要使用开关 - 只需使用一组:
HashSet<Type> NumericTypes = new HashSet<Type>
{
typeof(decimal), typeof(byte), typeof(sbyte),
typeof(short), typeof(ushort), ...
};
EDIT: One advantage of this over using a type code is that when new numeric types are introduced into .NET (e.g. BigIntegerand Complex) it's easy to adjust - whereas those types won'tget a type code.
编辑:与使用类型代码相比,这样做的一个优点是,当将新的数字类型引入 .NET(例如BigInteger和Complex)时,它很容易调整 - 而这些类型不会获得类型代码。
回答by Craig
Short answer: No.
简短的回答:没有。
Longer Answer: Nope.
更长的答案:不。
The fact is that many different types in C# can contain numeric data. Unless you know what to expect (Int, Double, etc) you need to use the "long" case statement.
事实上,C# 中的许多不同类型都可以包含数字数据。除非您知道会发生什么(Int、Double 等),否则您需要使用“long”case 语句。
回答by johnny g
oops! Misread the question! Personally, would roll with Skeet's.
哎呀!看错问题了!就个人而言,会和飞碟一起滚动。
hrm, sounds like you want to DoSomethingon Typeof your data. What you could do is the following
人力资源管理,像你的声音要DoSomething对Type您的数据。你可以做的是以下
public class MyClass
{
private readonly Dictionary<Type, Func<SomeResult, object>> _map =
new Dictionary<Type, Func<SomeResult, object>> ();
public MyClass ()
{
_map.Add (typeof (int), o => return SomeTypeSafeMethod ((int)(o)));
}
public SomeResult DoSomething<T>(T numericValue)
{
Type valueType = typeof (T);
if (!_map.Contains (valueType))
{
throw new NotSupportedException (
string.Format (
"Does not support Type [{0}].", valueType.Name));
}
SomeResult result = _map[valueType] (numericValue);
return result;
}
}
回答by MandoMando
They are all value types (except for bool and maybe enum). So you could simply use:
它们都是值类型(bool 和 enum 除外)。所以你可以简单地使用:
bool IsNumberic(object o)
{
return (o is System.ValueType && !(o is System.Boolean) && !(o is System.Enum))
}
回答by Guillaume
public static bool IsNumericType(Type type)
{
switch (Type.GetTypeCode(type))
{
case TypeCode.Byte:
case TypeCode.SByte:
case TypeCode.UInt16:
case TypeCode.UInt32:
case TypeCode.UInt64:
case TypeCode.Int16:
case TypeCode.Int32:
case TypeCode.Int64:
case TypeCode.Decimal:
case TypeCode.Double:
case TypeCode.Single:
return true;
default:
return false;
}
}
Note about optimization removed (see enzi comments)And if you really want to optimize it (losing readability and some safety...):
关于优化删除的注意事项(见 enzi 评论)如果你真的想优化它(失去可读性和一些安全性......):
public static bool IsNumericType(Type type)
{
TypeCode typeCode = Type.GetTypeCode(type);
//The TypeCode of numerical types are between SByte (5) and Decimal (15).
return (int)typeCode >= 5 && (int)typeCode <= 15;
}
public static bool IsNumericType(Type type)
{
TypeCode typeCode = Type.GetTypeCode(type);
//The TypeCode of numerical types are between SByte (5) and Decimal (15).
return (int)typeCode >= 5 && (int)typeCode <= 15;
}
回答by Jürgen Steinblock
None of the solutions takes Nullable into account.
没有一个解决方案将 Nullable 考虑在内。
I modified Jon Skeet's solution a bit:
我稍微修改了 Jon Skeet 的解决方案:
private static HashSet<Type> NumericTypes = new HashSet<Type>
{
typeof(int),
typeof(uint),
typeof(double),
typeof(decimal),
...
};
internal static bool IsNumericType(Type type)
{
return NumericTypes.Contains(type) ||
NumericTypes.Contains(Nullable.GetUnderlyingType(type));
}
I know I could just add the nullables itself to my HashSet. But this solution avoid the danger of forgetting to add a specific Nullable to your list.
我知道我可以将 nullables 本身添加到我的 HashSet 中。但是此解决方案避免了忘记将特定 Nullable 添加到列表中的危险。
private static HashSet<Type> NumericTypes = new HashSet<Type>
{
typeof(int),
typeof(int?),
...
};
回答by cimnine
Approach based on Philip's proposal, enhanced with SFun28's inner type checkfor Nullabletypes:
基于Philip's proposal 的方法,通过SFun28 的内部类型检查增强了Nullable类型:
public static class IsNumericType
{
public static bool IsNumeric(this Type type)
{
switch (Type.GetTypeCode(type))
{
case TypeCode.Byte:
case TypeCode.SByte:
case TypeCode.UInt16:
case TypeCode.UInt32:
case TypeCode.UInt64:
case TypeCode.Int16:
case TypeCode.Int32:
case TypeCode.Int64:
case TypeCode.Decimal:
case TypeCode.Double:
case TypeCode.Single:
return true;
case TypeCode.Object:
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
{
return Nullable.GetUnderlyingType(type).IsNumeric();
//return IsNumeric(Nullable.GetUnderlyingType(type));
}
return false;
default:
return false;
}
}
}
Why this? I had to check if a given Type typeis a numeric type, and not if an arbitrary object ois numeric.
为什么这个?我必须检查给定的Type type是否是数字类型,而不是任意的数字类型object o。

