49

但这里有一个例子:

Dim desiredType as Type
if IsNumeric(desiredType) then ...

编辑:我只知道类型,而不是值作为字符串。

好的,很遗憾我必须循环浏览 TypeCode。

但这是一个很好的方法:

 if ((desiredType.IsArray))
      return 0;

 switch (Type.GetTypeCode(desiredType))
 {
      case 3:
      case 6:
      case 7:
      case 9:
      case 11:
      case 13:
      case 14:
      case 15:
          return 1;
 }
 ;return 0;
4

10 回答 10

104

这里晚了几年,但这是我的解决方案(您可以选择是否包含布尔值)。解决 Nullable 情况。包括 XUnit 测试

/// <summary>
/// Determines if a type is numeric.  Nullable numeric types are considered numeric.
/// </summary>
/// <remarks>
/// Boolean is not considered numeric.
/// </remarks>
public static bool IsNumericType( Type type )
{
    if (type == null)
    {
        return false;
    }

    switch (Type.GetTypeCode(type))
    {
        case TypeCode.Byte:
        case TypeCode.Decimal:
        case TypeCode.Double:
        case TypeCode.Int16:
        case TypeCode.Int32:
        case TypeCode.Int64:
        case TypeCode.SByte:
        case TypeCode.Single:
        case TypeCode.UInt16:
        case TypeCode.UInt32:
        case TypeCode.UInt64:
            return true;
        case TypeCode.Object:
            if ( type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
            {
               return IsNumericType(Nullable.GetUnderlyingType(type));
            }
            return false;
    }
    return false;
}



/// <summary>
/// Tests the IsNumericType method.
/// </summary>
[Fact]
public void IsNumericTypeTest()
{
    // Non-numeric types
    Assert.False(TypeHelper.IsNumericType(null));
    Assert.False(TypeHelper.IsNumericType(typeof(object)));
    Assert.False(TypeHelper.IsNumericType(typeof(DBNull)));
    Assert.False(TypeHelper.IsNumericType(typeof(bool)));
    Assert.False(TypeHelper.IsNumericType(typeof(char)));
    Assert.False(TypeHelper.IsNumericType(typeof(DateTime)));
    Assert.False(TypeHelper.IsNumericType(typeof(string)));

    // Arrays of numeric and non-numeric types
    Assert.False(TypeHelper.IsNumericType(typeof(object[])));
    Assert.False(TypeHelper.IsNumericType(typeof(DBNull[])));
    Assert.False(TypeHelper.IsNumericType(typeof(bool[])));
    Assert.False(TypeHelper.IsNumericType(typeof(char[])));
    Assert.False(TypeHelper.IsNumericType(typeof(DateTime[])));
    Assert.False(TypeHelper.IsNumericType(typeof(string[])));
    Assert.False(TypeHelper.IsNumericType(typeof(byte[])));
    Assert.False(TypeHelper.IsNumericType(typeof(decimal[])));
    Assert.False(TypeHelper.IsNumericType(typeof(double[])));
    Assert.False(TypeHelper.IsNumericType(typeof(short[])));
    Assert.False(TypeHelper.IsNumericType(typeof(int[])));
    Assert.False(TypeHelper.IsNumericType(typeof(long[])));
    Assert.False(TypeHelper.IsNumericType(typeof(sbyte[])));
    Assert.False(TypeHelper.IsNumericType(typeof(float[])));
    Assert.False(TypeHelper.IsNumericType(typeof(ushort[])));
    Assert.False(TypeHelper.IsNumericType(typeof(uint[])));
    Assert.False(TypeHelper.IsNumericType(typeof(ulong[])));

    // numeric types
    Assert.True(TypeHelper.IsNumericType(typeof(byte)));
    Assert.True(TypeHelper.IsNumericType(typeof(decimal)));
    Assert.True(TypeHelper.IsNumericType(typeof(double)));
    Assert.True(TypeHelper.IsNumericType(typeof(short)));
    Assert.True(TypeHelper.IsNumericType(typeof(int)));
    Assert.True(TypeHelper.IsNumericType(typeof(long)));
    Assert.True(TypeHelper.IsNumericType(typeof(sbyte)));
    Assert.True(TypeHelper.IsNumericType(typeof(float)));
    Assert.True(TypeHelper.IsNumericType(typeof(ushort)));
    Assert.True(TypeHelper.IsNumericType(typeof(uint)));
    Assert.True(TypeHelper.IsNumericType(typeof(ulong)));

    // Nullable non-numeric types
    Assert.False(TypeHelper.IsNumericType(typeof(bool?)));
    Assert.False(TypeHelper.IsNumericType(typeof(char?)));
    Assert.False(TypeHelper.IsNumericType(typeof(DateTime?)));

    // Nullable numeric types
    Assert.True(TypeHelper.IsNumericType(typeof(byte?)));
    Assert.True(TypeHelper.IsNumericType(typeof(decimal?)));
    Assert.True(TypeHelper.IsNumericType(typeof(double?)));
    Assert.True(TypeHelper.IsNumericType(typeof(short?)));
    Assert.True(TypeHelper.IsNumericType(typeof(int?)));
    Assert.True(TypeHelper.IsNumericType(typeof(long?)));
    Assert.True(TypeHelper.IsNumericType(typeof(sbyte?)));
    Assert.True(TypeHelper.IsNumericType(typeof(float?)));
    Assert.True(TypeHelper.IsNumericType(typeof(ushort?)));
    Assert.True(TypeHelper.IsNumericType(typeof(uint?)));
    Assert.True(TypeHelper.IsNumericType(typeof(ulong?)));

    // Testing with GetType because of handling with non-numerics. See:
    // http://msdn.microsoft.com/en-us/library/ms366789.aspx

    // Using GetType - non-numeric
    Assert.False(TypeHelper.IsNumericType((new object()).GetType()));
    Assert.False(TypeHelper.IsNumericType(DBNull.Value.GetType()));
    Assert.False(TypeHelper.IsNumericType(true.GetType()));
    Assert.False(TypeHelper.IsNumericType('a'.GetType()));
    Assert.False(TypeHelper.IsNumericType((new DateTime(2009, 1, 1)).GetType()));
    Assert.False(TypeHelper.IsNumericType(string.Empty.GetType()));

    // Using GetType - numeric types
    // ReSharper disable RedundantCast
    Assert.True(TypeHelper.IsNumericType((new byte()).GetType()));
    Assert.True(TypeHelper.IsNumericType(43.2m.GetType()));
    Assert.True(TypeHelper.IsNumericType(43.2d.GetType()));
    Assert.True(TypeHelper.IsNumericType(((short)2).GetType()));
    Assert.True(TypeHelper.IsNumericType(((int)2).GetType()));
    Assert.True(TypeHelper.IsNumericType(((long)2).GetType()));
    Assert.True(TypeHelper.IsNumericType(((sbyte)2).GetType()));
    Assert.True(TypeHelper.IsNumericType(2f.GetType()));
    Assert.True(TypeHelper.IsNumericType(((ushort)2).GetType()));
    Assert.True(TypeHelper.IsNumericType(((uint)2).GetType()));
    Assert.True(TypeHelper.IsNumericType(((ulong)2).GetType()));
    // ReSharper restore RedundantCast

    // Using GetType - nullable non-numeric types
    bool? nullableBool = true;
    Assert.False(TypeHelper.IsNumericType(nullableBool.GetType()));
    char? nullableChar = ' ';
    Assert.False(TypeHelper.IsNumericType(nullableChar.GetType()));
    DateTime? nullableDateTime = new DateTime(2009, 1, 1);
    Assert.False(TypeHelper.IsNumericType(nullableDateTime.GetType()));

    // Using GetType - nullable numeric types
    byte? nullableByte = 12;
    Assert.True(TypeHelper.IsNumericType(nullableByte.GetType()));
    decimal? nullableDecimal = 12.2m;
    Assert.True(TypeHelper.IsNumericType(nullableDecimal.GetType()));
    double? nullableDouble = 12.32;
    Assert.True(TypeHelper.IsNumericType(nullableDouble.GetType()));
    short? nullableInt16 = 12;
    Assert.True(TypeHelper.IsNumericType(nullableInt16.GetType()));
    short? nullableInt32 = 12;
    Assert.True(TypeHelper.IsNumericType(nullableInt32.GetType()));
    short? nullableInt64 = 12;
    Assert.True(TypeHelper.IsNumericType(nullableInt64.GetType()));
    sbyte? nullableSByte = 12;
    Assert.True(TypeHelper.IsNumericType(nullableSByte.GetType()));
    float? nullableSingle = 3.2f;
    Assert.True(TypeHelper.IsNumericType(nullableSingle.GetType()));
    ushort? nullableUInt16 = 12;
    Assert.True(TypeHelper.IsNumericType(nullableUInt16.GetType()));
    ushort? nullableUInt32 = 12;
    Assert.True(TypeHelper.IsNumericType(nullableUInt32.GetType()));
    ushort? nullableUInt64 = 12;
    Assert.True(TypeHelper.IsNumericType(nullableUInt64.GetType()));
}
于 2011-03-03T15:24:52.837 回答
28

您可以使用以下Type.GetTypeCode()方法确定变量是否为数字:

TypeCode typeCode = Type.GetTypeCode(desiredType);

if (typeCode == TypeCode.Double || typeCode == TypeCode.Integer || ...)
     return true;

您需要在“...”部分完成所有可用的数字类型;)

更多详细信息:TypeCode 枚举

于 2008-09-23T22:56:28.117 回答
7

伟大的文章在这里探索 IsNumeric for C#

选项1:

引用 Microsoft.VisualBasic.dll,然后执行以下操作:

if (Microsoft.VisualBasic.Information.IsNumeric("5"))
{
 //Do Something
}

选项 2:

public static bool Isumeric (object Expression)
{
    bool f;
    ufloat64 a;
    long l;

    IConvertible iConvertible = null;
    if ( ((Expression is IConvertible)))
    {
       iConvertible = (IConvertible) Expression;
    }

    if (iConvertible == null)
{
   if ( ((Expression is char[])))
   {
       Expression = new String ((char[]) Expression);
       goto IL_002d; // hopefully inserted by optimizer
   }
   return 0;
}
IL_002d:
TypeCode typeCode = iConvertible.GetTypeCode ();
if ((typeCode == 18) || (typeCode == 4))
{
    string str = iConvertible.ToString (null);
   try
   {
        if ( (StringType.IsHexOrOctValue (str, l)))
   {
        f = true;
        return f;
   }
}
catch (Exception )
{
    f = false;
    return f;
};
return DoubleType.TryParse (str, a);
}
return Utils.IsNumericTypeCode (typeCode);
}

internal static bool IsNumericType (Type typ)
{
bool f;
TypeCode typeCode;
if ( (typ.IsArray))
{
    return 0;
}
switch (Type.GetTypeCode (typ))
{
case 3: 
case 6: 
case 7: 
case 9: 
case 11: 
case 13: 
case 14: 
case 15: 
   return 1;
};
return 0;
}
于 2008-09-23T23:04:02.480 回答
5

如果您有对实际对象的引用,这里有一个简单的 C# 解决方案,非常简单:

    /// <summary>
    /// Determines whether the supplied object is a .NET numeric system type
    /// </summary>
    /// <param name="val">The object to test</param>
    /// <returns>true=Is numeric; false=Not numeric</returns>
    public static bool IsNumeric(ref object val)
    {
        if (val == null)
            return false;

        // Test for numeric type, returning true if match
        if 
            (
            val is double || val is float || val is int || val is long || val is decimal || 
            val is short || val is uint || val is ushort || val is ulong || val is byte || 
            val is sbyte
            )
            return true;

        // Not numeric
        return false;
    }
于 2011-05-22T19:18:45.137 回答
5

感谢@SFun28 和@nawfal(谢谢!),我使用了他们的两个答案,稍作调整并提出了这些扩展方法:

public static class ReflectionExtensions
{
    public static bool IsNullable(this Type type) {
        return
            type != null &&
            type.IsGenericType && 
            type.GetGenericTypeDefinition() == typeof(Nullable<>);
    }

    public static bool IsNumeric(this Type type) {
        if (type == null || type.IsEnum)
            return false;

        if (IsNullable(type))
            return IsNumeric(Nullable.GetUnderlyingType(type));

        switch (Type.GetTypeCode(type)) {
            case TypeCode.Byte:
            case TypeCode.Decimal:
            case TypeCode.Double:
            case TypeCode.Int16:
            case TypeCode.Int32:
            case TypeCode.Int64:
            case TypeCode.SByte:
            case TypeCode.Single:
            case TypeCode.UInt16:
            case TypeCode.UInt32:
            case TypeCode.UInt64:
                return true;
            default:
                return false;
        }
    }
}
于 2015-07-29T19:13:54.647 回答
4

我知道这是一个非常晚的答案,但这是我使用的功能:

public static bool IsNumeric(Type type)
{
    var t = Nullable.GetUnderlyingType(type) ?? type;
    return t.IsPrimitive || t == typeof(decimal);
}

如果您想排除char为数字类型,则可以使用以下示例:

return (t.IsPrimitive || t == typeof(decimal)) && t != typeof(char);

根据 MSDN

基本类型是 Boolean、Byte、SByte、Int16、UInt16、Int32、UInt32、Int64、UInt64、IntPtr、UIntPtr、Char、Double 和 Single。

注意:此检查包括IntPtrUIntPtr

这是与通用扩展方法相同的功能(我知道这不适用于 OP 的情况,但其他人可能会发现它很有用):

public static bool IsNumeric<T>(this T value)
{
    var t = Nullable.GetUnderlyingType(value.GetType()) ?? value.GetType();
    return t.IsPrimitive || t == typeof(decimal);
}
于 2017-03-07T17:18:47.173 回答
3

这就是 MS 如何在System.Dynamic.Utils.TypeUtils内部类中实现它的。结果他们不认为System.Decimal是数字类型(Decimal从枚举中省略)。有趣的是,MS 发现System.Char类型是数字的。否则,它与 SFun28 的答案完全相同。我想他的回答是“更正确”。

internal static bool IsNumeric(Type type)
{
    type = type.GetNonNullableType();
    if (!type.IsEnum)
    {
        switch (Type.GetTypeCode(type))
        {
        case TypeCode.Char:
        case TypeCode.SByte:
        case TypeCode.Byte:
        case TypeCode.Int16:
        case TypeCode.UInt16:
        case TypeCode.Int32:
        case TypeCode.UInt32:
        case TypeCode.Int64:
        case TypeCode.UInt64:
        case TypeCode.Single:
        case TypeCode.Double:
            return true;
        }
    }
    return false;
}

//where GetNonNullableType is defined as

internal static Type GetNonNullableType(this Type type)
{
    if (type.IsNullableType())
    {
        return type.GetGenericArguments()[0];
    }
    return type;
}

//where IsNullableType is defined as

internal static bool IsNullableType(this Type type)
{
    return type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>);
}
于 2014-01-18T12:41:05.840 回答
2
''// Return true if a type is a numeric type.
Private Function IsNumericType(ByVal this As Type) As Boolean
    ''// All the numeric types have bits 11xx set whereas non numeric do not.
    ''// That is if you include char type which is 4(decimal) = 100(binary).
    If this.IsArray Then Return False
    If (Type.GetTypeCode(this) And &HC) > 0 Then Return True
    Return False
End Function
于 2010-03-15T17:30:47.557 回答
1

您现在可以使用 .NET Framework 方法

typeof(decimal?).IsNumericType()
于 2019-08-07T14:35:38.363 回答
-5

使用 Type.IsValueType() 和 TryParse():

public bool IsInteger(Type t)
{
   int i;
   return t.IsValueType && int.TryParse(t.ToString(), out i);
}
于 2008-09-23T23:12:32.697 回答