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 interrupteur sur le Type.FullName
.C# - comment déterminer si un Type est un nombre
Répondre
Essayez ceci:
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 unique.
Prendre Guillaume's solution 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;
}
}
Utilisation:
int i = 32;
i.IsNumericType(); // True
string s = "Hello World";
s.IsNumericType(); // False
Donc le type 'decimal' n'est pas numérique? – LukeH
Les types primitifs sont les suivants: Booléen, Octet, SByte, Int16, UInt16, Int32, UInt32, Int64, UInt64, IntPtr, UIntPtr, Char, Double et Single. –
@Luke - bonne question. C'est une structure - vous devez donc définir numérique. –
Vous pouvez utiliser Type.IsPrimitive puis trier les types Boolean
et Char
, quelque chose comme ceci:
bool IsNumeric(Type type)
{
return type.IsPrimitive && type!=typeof(char) && type!=typeof(bool);
}
EDIT: Vous pouvez exclure les IntPtr
et UIntPtr
types aussi bien, si vous n » Je considère qu'ils sont numériques.
Malheureusement, ces types n'ont pas beaucoup en commun, sauf qu'ils sont tous les types de valeurs. Mais pour éviter un long switch-case, vous pouvez simplement définir une liste en lecture seule avec tous ces types, puis vérifier simplement si le type donné est dans la liste.
Ne pas utiliser un interrupteur - il suffit d'utiliser un ensemble:
HashSet<Type> NumericTypes = new HashSet<Type>
{
typeof(decimal), typeof(byte), typeof(sbyte),
typeof(short), typeof(ushort), ...
};
EDIT: Un avantage de ce rapport à l'utilisation d'un code de type est que lorsque les nouveaux types numériques sont introduits dans .NET (par exemple BigInteger et Complex) il est facile à ajuster - alors que les types ne vont pas obtenir un code de type.
Réponse courte: Non
Longer Réponse: Non.
Le fait est que de nombreux types différents en C# peuvent contenir des données numériques. Si vous ne savez pas à quoi vous attendre (Int, Double, etc.), vous devez utiliser l'instruction "long".
oups! Mal lire la question! Personnellement, roulerait avec Skeet's.
HRM, sonne comme vous voulez DoSomething
sur Type
de vos données. Ce que vous pouvez faire est le suivant
public class MyClass
{
private readonly Dictionary<Type, Func<SomeResult, object>> _map =
new Dictionary<Type, Func<SomeResult, object>>();
public MyClass()
{
_map.Add (typeof (int), o => return SomeTypeSafeMethod ((int)(o)));
}
public SomeResult DoSomething<T>(T numericValue)
{
Type valueType = typeof (T);
if (!_map.Contains (valueType))
{
throw new NotSupportedException (
string.Format (
"Does not support Type [{0}].", valueType.Name));
}
SomeResult result = _map[valueType] (numericValue);
return result;
}
}
Ils sont tous les types de valeur (sauf pour bool et peut-être enum).Donc, vous pouvez simplement utiliser:
bool IsNumberic(object o)
{
return (o is System.ValueType && !(o is System.Boolean) && !(o is System.Enum))
}
Cela retournera true pour toute 'struct' définie par l'utilisateur ... Je ne pense pas que ce soit ce que vous voulez. –
Vous avez raison. Les types numériques intégrés sont également des structures. Il vaut donc mieux aller avec la comparaison Primitive alors. – MandoMando
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;
}
}
Remarque sur l'optimisation retirée (voir les commentaires Enzi)
Et si vous voulez vraiment optimiser (perdre la lisibilité et une certaine 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;
}
Je sais que cette réponse est ancienne, mais je suis récemment tombé sur un tel changement: n'utilisez pas l'optimisation suggérée! J'ai regardé le code IL généré à partir d'un tel commutateur, et noté que le compilateur applique déjà l'optimisation (dans IL 5 est soustrait du code de type et ensuite les valeurs de 0 à 10 sont considérées comme vraies). D'où le commutateur devrait être utilisé pour qu'il soit plus lisible et plus sûr et tout aussi rapide. – enzi
Si vous voulez vraiment l'optimiser et que vous ne vous souciez pas de la lisibilité, le code optimal serait 'return non coché ((uint) Type.GetTypeCode (type) - 5u) <= 10u;' supprimant ainsi la branche introduite par '&&' . – AnorZaken
Aucune des solutions prend Nul lable en compte.
J'ai modifié la solution de Jon Skeet un peu:
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 peux ajouter les nullables lui-même à 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?),
...
};
Un type nullable est-il vraiment numérique? Null n'est pas un nombre, à ma connaissance. – IllidanS4
Cela dépend de ce que vous voulez réaliser. Dans mon cas, j'avais aussi besoin d'inclure des valeurs nulles. Mais je pourrais aussi penser à des situations où ce n'est pas un comportement désiré. –
approche basée sur Philip's proposal, renforcée avec SFun28's inner type check pour Nullable
types:
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? J'ai dû vérifier si un Type type
donné est un type numérique, et non si un object o
arbitraire est numérique.
Fondamentalement, la solution de Skeet, mais vous pouvez le réutiliser avec les types nullables comme suit:
public static class TypeHelper
{
private static readonly HashSet<Type> NumericTypes = new HashSet<Type>
{
typeof(int), typeof(double), typeof(decimal),
typeof(long), typeof(short), typeof(sbyte),
typeof(byte), typeof(ulong), typeof(ushort),
typeof(uint), typeof(float)
};
public static bool IsNumeric(Type myType)
{
return NumericTypes.Contains(Nullable.GetUnderlyingType(myType) ?? myType);
}
}
Cela peut fonctionner aussi bien. Cependant, vous pouvez le suivre avec un Type.Parse pour le lancer comme vous le souhaitez par la suite.
public bool IsNumeric(object value)
{
float testValue;
return float.TryParse(value.ToString(), out testValue);
}
modifiés au pigeon d'argile et de la solution de arviman utilisant Generics
, Reflection
et C# v6.0
.
private static readonly HashSet<Type> m_numTypes = new HashSet<Type>
{
typeof(int), typeof(double), typeof(decimal),
typeof(long), typeof(short), typeof(sbyte),
typeof(byte), typeof(ulong), typeof(ushort),
typeof(uint), typeof(float), typeof(BigInteger)
};
Suivi par:
public static bool IsNumeric<T>(this T myType)
{
var IsNumeric = false;
if(myType != null)
{
IsNumeric = m_numTypes.Contains(myType.GetType());
}
return IsNumeric;
}
Utilisation pour (T item)
:
if (item.IsNumeric()) {}
null
retourne false.
Avec C# 7 cette méthode me donne de meilleures performances que le cas de l'interrupteur sur TypeCode
et HashSet<Type>
:
public static bool IsNumeric(this object o) => o is byte || o is sbyte || o is ushort || o is uint || o is ulong || o is short || o is int || o is long || o is float || o is double || o is decimal;
Les tests sont suivants:
public static class Extensions
{
public static HashSet<Type> NumericTypes = new HashSet<Type>()
{
typeof(byte), typeof(sbyte), typeof(ushort), typeof(uint), typeof(ulong), typeof(short), typeof(int), typeof(long), typeof(decimal), typeof(double), typeof(float)
};
public static bool IsNumeric1(this object o) => NumericTypes.Contains(o.GetType());
public static bool IsNumeric2(this object o) => o is byte || o is sbyte || o is ushort || o is uint || o is ulong || o is short || o is int || o is long || o is decimal || o is double || o is float;
public static bool IsNumeric3(this object o)
{
switch (o)
{
case Byte b:
case SByte sb:
case UInt16 u16:
case UInt32 u32:
case UInt64 u64:
case Int16 i16:
case Int32 i32:
case Int64 i64:
case Decimal m:
case Double d:
case Single f:
return true;
default:
return false;
}
}
public static bool IsNumeric4(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;
}
}
}
class Program
{
static void Main(string[] args)
{
var count = 100000000;
//warm up calls
for (var i = 0; i < count; i++)
{
i.IsNumeric1();
}
for (var i = 0; i < count; i++)
{
i.IsNumeric2();
}
for (var i = 0; i < count; i++)
{
i.IsNumeric3();
}
for (var i = 0; i < count; i++)
{
i.IsNumeric4();
}
//Tests begin here
var sw = new Stopwatch();
sw.Restart();
for (var i = 0; i < count; i++)
{
i.IsNumeric1();
}
sw.Stop();
Debug.WriteLine(sw.ElapsedMilliseconds);
sw.Restart();
for (var i = 0; i < count; i++)
{
i.IsNumeric2();
}
sw.Stop();
Debug.WriteLine(sw.ElapsedMilliseconds);
sw.Restart();
for (var i = 0; i < count; i++)
{
i.IsNumeric3();
}
sw.Stop();
Debug.WriteLine(sw.ElapsedMilliseconds);
sw.Restart();
for (var i = 0; i < count; i++)
{
i.IsNumeric4();
}
sw.Stop();
Debug.WriteLine(sw.ElapsedMilliseconds);
}
- 1. Déterminer si un type est un type anonyme
- 2. Déterminer si un type est statique
- 3. Ruby - déterminer si un nombre est un premier
- 4. Déterminer si un type est un type de référence ou un type de valeur
- 5. Comment détecter si un nombre donné est un nombre entier?
- 6. C# Comment déterminer si un nombre est un multiple d'un autre?
- 7. Comment déterminer si un gif est animé?
- 8. Comment puis-je déterminer si un nombre est dans un pourcentage d'un autre nombre?
- 9. Comment déterminer si Type est une structure?
- 10. Comment puis-je déterminer si System.Type est un type personnalisé ou un type de cadre?
- 11. Comment déterminer si un type d'interface implémente un attribut personnalisé
- 12. Comment déterminer si un groupe est un groupe de sécurité?
- 13. Comment déterminer si un pthread est actif?
- 14. Comment déterminer si objet est un NSNumber
- 15. objective-c déterminer si le paramètre est un objet
- 16. .NET: Comment déterminer si un objet est un objet COM?
- 17. C Type # classe - Comment déterminer si elle est un cadre standard .net classe
- 18. Déterminer si l'erreur $ .ajax est un délai
- 19. Objectif C: Comment savoir si un nombre est divisible par un autre nombre?
- 20. Comment déterminer si le nombre a chiffres identiques en C
- 21. Comment détecter si le type est un autre type générique
- 22. Comment déterminer si un type implémente un type d'interface générique spécifique
- 23. Comment déterminer le nombre de bits dans un paramètre de constante intégrale de type non-type?
- 24. C# comment déterminer si un smartphone est un appareil standard ou professionnel?
- 25. Déterminer si un répertoire est inscriptible
- 26. Comment vérifier si un élément d'une liste est un nombre?
- 27. NHibernate: Déterminer si une propriété est mappée à un champ
- 28. Comment puis-je déterminer si le chiffre est un nombre pair?
- 29. Comment déterminer si une variante est un nombre entier en VBA?
- 30. Comment puis-je utiliser une regex pour déterminer si un nombre est divisible par 5?
Dupe de beaucoup, beaucoup, beaucoup. Pourquoi cela n'a-t-il pas encore été fermé? – Noldorin
Dupliquer de http://stackoverflow.com/questions/1130698/ et très proche de certains autres. –
duplication possible de [En utilisant .Net, comment puis-je déterminer si un type est un ValueType numérique?] (Http: // stackoverflow.com/questions/124411/using-net-comment-peut-je-déterminer-si-un-type-est-un-type-valeur-numérique) – nawfal