使用.Net,如何确定类型是否为数值ValueType?

Nes*_*cio 48 .net reflection

但这是一个例子:

Dim desiredType as Type
if IsNumeric(desiredType) then ...
Run Code Online (Sandbox Code Playgroud)

编辑:我只知道类型,而不是字符串的值.

好的,不幸的是我必须循环使用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;
Run Code Online (Sandbox Code Playgroud)

SFu*_*n28 100

在这里晚了几年,但这是我的解决方案(您可以选择是否包含布尔值).解决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()));
}
Run Code Online (Sandbox Code Playgroud)

  • 要添加到此gravediggery,如果要定义IsNumericType以获取类型,为什么不递归地将Nullable.GetUnderlyingType的结果传递给同一函数并返回其值? (4认同)
  • 为什么不在静态类中声明这个方法并使其可用于Type:`public static bool IsNumeric(this Type type){/*...*/}`? (4认同)
  • 很好的解决方案,也为测试+1.肯定比接受的答案好. (3认同)
  • 很好的解决方案,请注意使用上述逻辑将Enum归类为整数 (2认同)

Jon*_*jap 28

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

TypeCode typeCode = Type.GetTypeCode(desiredType);

if (typeCode == TypeCode.Double || typeCode == TypeCode.Integer || ...)
     return true;
Run Code Online (Sandbox Code Playgroud)

您需要在"..."部分中填写所有可用的数字类型;)

更多细节:TypeCode枚举

  • 更好:Foreach(TypeCode typecode in new TypeCode [] {TypeCode.Double [...]}如果typecode == Type.GetTypeCode(desiredType)返回true;返回false; (2认同)
  • 为什么你们不能为我们这样做,所以我们可以复制/粘贴? (2认同)

Jor*_*ira 7

这篇很棒的文章探索C#的IsNumeric.

选项1:

参考Microsoft.VisualBasic.dll,然后执行以下操作:

if (Microsoft.VisualBasic.Information.IsNumeric("5"))
{
 //Do Something
}
Run Code Online (Sandbox Code Playgroud)

选项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;
}
Run Code Online (Sandbox Code Playgroud)


Tod*_*ier 6

感谢@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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • @Riga我可以看到枚举是一个灰色区域,但我会犯错误。假设您正在构建一个 JSON 序列化器并希望将枚举序列化为字符串。在这种情况下,您不想将它们视为数字。 (2认同)

Jos*_* T. 6

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

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

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

return (t.IsPrimitive || t == typeof(decimal)) && t != typeof(char);
Run Code Online (Sandbox Code Playgroud)

根据 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);
}
Run Code Online (Sandbox Code Playgroud)


Mar*_*nes 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;
    }
Run Code Online (Sandbox Code Playgroud)