133 votes

C # - Comment déterminer si un type est un nombre

Existe-t-il un moyen de déterminer si un type .Net donné est un nombre? Par exemple: System.UInt32/UInt16/Double sont tous des nombres. Je veux éviter un long cas sur le Type.FullName .

134voto

Philip Wallace Points 4550

Essaye ça:

 Type type = object.GetType();
bool isNumber = (type.IsPrimitiveImple && type != typeof(bool) && type != typeof(char));
 

Les types primitifs sont Boolean, Byte, SByte, Int16, UInt16, Int32, UInt32, Int64, UInt64, Char, Double et Single.

Prenant la solution de Guillaume un peu plus loin:

 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
 

107voto

Jon Skeet Points 692016

N'utilisez pas d'interrupteur - utilisez simplement un ensemble:

 HashSet<Type> NumericTypes = new HashSet<Type>
{
    typeof(decimal), typeof(byte), typeof(sbyte),
    typeof(short), typeof(ushort), ...
};
 

ÉDITER: Un des avantages de cette méthode par rapport au code de type est que, lorsque de nouveaux types numériques sont introduits dans .NET (par exemple, BigInteger et Complex ), il est facile de les ajuster - alors que ces types ne reçoivent pas de code de type.

77voto

SchlaWiener Points 9682

Aucune des solutions ne prend Nullable en compte.

J'ai légèrement modifié la solution de 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));
    }
 

Je sais que je pourrais simplement ajouter les éléments nullables à mon HashSet. Mais cette solution évite le danger d'oublier d'ajouter un Nullable spécifique à votre liste.

     private static HashSet<Type> NumericTypes = new HashSet<Type>
    {
        typeof(int),
        typeof(int?),
        ...
    };
 

40voto

Guillaume Points 5649
 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;
  }
}
 

Et si vous voulez vraiment l'optimiser (perte de lisibilité et de sécurité ...):

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

11voto

cimnine Points 1052

Approche basée sur la proposition de Philip , améliorée avec la vérification de type interne de SFun28 pour les types 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;
        }
    }
}
 

Pourquoi ça? Je devais vérifier si un Type type est un type numérique, et non si un object o arbitraire est numérique.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X