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/Double
are 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 Boolean
and Char
types, 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 IntPtr
and UIntPtr
types 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 DoSomething
on Type
of 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 Nullable
types:
基于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 type
is a numeric type, and not if an arbitrary object o
is numeric.
为什么这个?我必须检查给定的Type type
是否是数字类型,而不是任意的数字类型object o
。