.NET을 사용하여 유형이 숫자 밸류 타입인지 어떻게 결정할 수 있습니까?

StackOverflow https://stackoverflow.com/questions/124411

  •  02-07-2019
  •  | 
  •  

문제

그러나 여기에 예가 있습니다.

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

편집하다: 나는 문자열로서의 값이 아니라 유형을 알고 있습니다.

알았어, 불행히도 나는 타입 코드를 순환해야한다.

그러나 이것은 좋은 방법입니다.

 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;
도움이 되었습니까?

해결책

몇 년 늦었지만 여기에 내 해결책이 있습니다 (부울 포함 여부를 선택할 수 있음). 귀중한 경우를 해결합니다. 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()));
}

다른 팁

변수가 Type.GetTypeCode() 방법:

TypeCode typeCode = Type.GetTypeCode(desiredType);

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

"..."부분;)에서 사용 가능한 모든 숫자 유형을 완료해야합니다.

자세한 내용은 여기를 참조하십시오. 타이프 코드 열거

여기에 훌륭한 기사 C#에 대한 isnumeric 탐색.

옵션 1:

참조 Microsoft.visualBasic.dll, 다음을 수행하십시오.

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

Option 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;
}

실제 객체에 대한 참조가 있다면 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;
    }

@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;
        }
    }
}

이것이 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<>);
}

나는 이것이 매우 늦은 답변이라는 것을 알고 있지만 여기에 내가 사용하는 기능이 있습니다.

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에 따르면:

원시 유형은 부울, 바이트, SBYTE, int16, UINT16, int32, uint32, int64, uint64, intptr, uintptr, char, double 및 single입니다.

참고 :이 점검에는 포함됩니다 intptr 그리고 uintptr.

다음은 일반 확장 방법과 동일한 기능입니다 (OP의 경우에는 이것이 효과가 없지만 다른 사람이 유용 할 수 있음을 알고 있습니다).

public static bool IsNumeric<T>(this T value)
{
    var t = Nullable.GetUnderlyingType(value.GetType()) ?? value.GetType();
    return t.IsPrimitive || t == typeof(decimal);
}
''// 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

type.isvaluetype () 및 tryparse ()를 사용합니다.

public bool IsInteger(Type t)
{
   int i;
   return t.IsValueType && int.TryParse(t.ToString(), out i);
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top