Pero he aquí un ejemplo:

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

EDICIÓN: yo sólo conozco al Tipo, no el Valor como una cadena.

Ok, así que por desgracia, tengo que ciclo a través de la TypeCode.

Pero esta es una buena manera de hacerlo:

 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;
  • Un par de años de retraso aquí, pero ¿por qué IsArray importa? Una Matriz es un Objeto y debe fallar su interruptor.
InformationsquelleAutor Nescio | 2008-09-23

10 Comentarios

  1. 99

    Un par de años de retraso aquí, pero aquí está mi solución (usted puede elegir si desea incluir booleano). Resuelve por el que aceptan valores null caso. XUnit prueba incluye

    ///<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()));
    }
    • Para agregar a este gravediggery, si vas a definir IsNumericType a tomar un tipo, ¿por qué no de forma recursiva pasar el resultado de que aceptan valores null.GetUnderlyingType para la misma función y devolver su valor?
    • yup…gran sugerencia. más elegante de esa manera. actualizado post.
    • por qué no declarar este método en una clase estática y ponerlo a disposición del Tipo: public static bool IsNumeric(this Type type) { /*...*/ } ?
    • Acepta valores null.GetUnderlyingType() devuelve null si el argumento de tipo no es un valor que aceptan valores null. Así que no creo que usted necesita para comprobar IsGenericType y GetGenericTypeDefinition().
    • Solución agradable y también +1 para las pruebas. Definitivamente mejor que aceptó contestar.
    • Solución agradable. Estoy tratando de volver a trabajar algún código que usa esta en una biblioteca portátil (PCL). Dependiendo del perfil utilizado, el TypeCode enum y GetTypeCode() no están disponibles. Deseo que había otra manera de que funcionara en el PCL!
    • Solución agradable, acaba de ser conscientes de que una Enumeración sería clasificado como un entero usando la lógica anterior
    • No puedo creer que entre todas esas pruebas que no son de un tipo de enumeración, incluso si usted cree que la enumeración debe ser clasificado como un tipo numérico. Tenga en cuenta que MS en su aplicación no considerar enum como de tipo numérico (en mi respuesta), pero yo creo que MS de la otra decisión como char es numérico mientras decimal no es defectuoso. Todd Menier tiene la mejor respuesta aquí que combina todo lo bueno y lo deja fuera de las rarezas: stackoverflow.com/a/31709198/661933
    • buena captura, en la enumeración. gracias por el enlace a Todd respuesta.

  2. 28

    Usted puede averiguar si una variable es numérica utilizando el Type.GetTypeCode() método:

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

    Que usted necesitará para completar todos los tipos numéricos en los «…» de la parte 😉

    Más detalles aquí: TypeCode Enumeración

    • Tenía la esperanza de no tener que comprobar cada tipo, pero esto funciona gracias!
    • Para su INFORMACIÓN, este código no funcionará si son tipos que aceptan valores null. En ese caso, el typecode devuelve como Objeto. Todavía tratando de averiguar cómo conseguir alrededor de eso. Nadie?
    • Mejor: Foreach (TypeCode typecode en nueva TypeCode[] { TypeCode.Doble […] } si typecode == Tipo.GetTypeCode(desiredType) return true; return false;
    • ¿por qué no es lo que ustedes acaba hacer por nosotros para que podamos copiar/pegar?
    • ¿Por qué utilizar TypeCode? En C# podemos usar if ((desiredType is double) || (desiredType is int) || ... ) return true;, ¿verdad?
    • usted puede hacer «si (1 es de tipo int)» en C#, no «si (1.GetType() es de tipo int)». Espero que usted consigue la idea.

  3. 7

    Gran artículo aquí Explorar IsNumeric para C#.

    Opción 1:

    Referencia Microsoft.VisualBasic.dll, a continuación, haga lo siguiente:

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

    Opción 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;
    }
  4. 5

    Si quieres tener una referencia a un objeto real, he aquí una solución sencilla para C# que es muy sencillo:

        ///<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;
    }
    • Se me ocurrió algo similar. ¿Puedo preguntar por qué usted está utilizando el «ref» palabra clave con el val argumento.
    • Este es en realidad el mismo que el typecode soluciones basadas en la anterior, excepto que es más lento…
  5. 4

    Con todo el debido crédito a @SFun28 y @nawfal (¡gracias!), He utilizado tanto de sus respuestas, ajustado ligeramente y se acercó con estos métodos de extensión:

    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;
    }
    }
    }
    • no entiendo por qué si ‘tipo.IsEnum’ devuelve false?
    • Pude ver las enumeraciones de ser una zona gris, pero me gustaría errar en el lado de la falsa. Digamos que usted está construyendo un JSON serializador y quiere enumeraciones serializado a las cadenas. En el caso de que usted no quiere tratar como un número.
  6. 3

    Esta es la forma MS ha implementado en System.Dynamic.Utils.TypeUtils que es una clase interna. Resulta que ellos no consideran System.Decimal a ser de tipo numérico (Decimal se omite de la enumeración). Y curiosamente MS encuentra System.Char tipo numérico. De lo contrario, es exactamente el mismo que SFun28 la respuesta. Supongo que su respuesta es «más correcta».

    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<>);
    }
    • Me pregunto si hay una manera de optimizar aún más el uso de este bit a bit de operaciones y otras cosas…
  7. 3

    Yo sé que es MUY tarde la respuesta, pero aquí es la función que yo uso:

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

    Si desea excluir char de tipo numérico, a continuación, puede utilizar este ejemplo:

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

    Según la MSDN:

    Los tipos primitivos son Boolean, Byte, SByte, Int16, UInt16, Int32,
    UInt32, Int64, UInt64, IntPtr, UIntPtr, Char, Double y Único.

    Nota: Esta comprobación incluye IntPtr y UIntPtr.

    Aquí es la misma función que una extensión genérica del método (sé que esto no funciona para el OP del caso, pero alguien podría encontrar útil):

    public static bool IsNumeric<T>(this T value)
    {
    var t = Nullable.GetUnderlyingType(value.GetType()) ?? value.GetType();
    return t.IsPrimitive || t == typeof(decimal);
    }
  8. 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
    • Si esto es cierto, esta es una MUUUUY mejor respuesta, la bondad!
    • Totalmente equivocado, SByte es numérico y tiene un id de 5, que es el ‘0101’, así que esto está mal.
  9. -5

    Tipo De Uso.IsValueType() y TryParse():

    public bool IsInteger(Type t)
    {
    int i;
    return t.IsValueType && int.TryParse(t.ToString(), out i);
    }
    • «t» no es una variable del Tipo en cuestión. Él es del tipo en cuestión. t nunca va a ser un número en este código.

Dejar respuesta

Please enter your comment!
Please enter your name here