Je voudrais vérifier si un objet est un numéro afin que .ToString()
se traduirait par une chaîne contenant des chiffres et +
, -
,.
Est-ce possible par simple enregistrement de type .net (comme:) if (p is Number)
?
Ou dois-je convertir en chaîne, puis essayer d'analyser pour doubler?
Mise à jour: pour clarifier mon objet est int, uint, float, double, etc., ce n'est pas une chaîne. J'essaie de créer une fonction qui sérialiserait n'importe quel objet en xml comme ceci:
<string>content</string>
ou
<numeric>123.3</numeric>
ou lever une exception.
c#
.net
serialization
xml-serialization
Piotr Czapla
la source
la source
Réponses:
Vous aurez simplement besoin de faire une vérification de type pour chacun des types numériques de base.
Voici une méthode d'extension qui devrait faire le travail:
Cela devrait couvrir tous les types numériques.
Mettre à jour
Il semble que vous souhaitiez réellement analyser le nombre d'une chaîne lors de la désérialisation. Dans ce cas, il serait probablement préférable de l'utiliser
double.TryParse
.Bien sûr, cela ne gérerait pas de très grands entiers / décimales longues, mais si tel est le cas, vous devez simplement ajouter des appels supplémentaires à
long.TryParse
/decimal.TryParse
/ quoi que ce soit d'autre.la source
Tiré du blog de Scott Hanselman :
la source
double.Parse(double.MaxValue.ToString())
provoque unOverflowException
. Vous pouvez remédier à cela en fournissant le modificateur aller-retour.ToString("R")
dans ce cas, mais cette surcharge n'est pas disponibleConvert.ToString(...)
car nous ne connaissons pas le type. Je sais que c'est un peu un cas marginal, mais je suis tombé dessus en écrivant des tests pour ma propre.IsNumeric()
extension. Ma "solution" était d'ajouter un commutateur de vérification de type avant d'essayer d'analyser quoi que ce soit, voir ma réponse à cette question pour le code.Tirez parti de la propriété IsPrimitive pour créer une méthode d'extension pratique:
EDIT: Corrigé selon les commentaires. Les génériques ont été supprimés depuis les types de valeur des boîtes .GetType (). Correctif également inclus pour les valeurs Nullable.
la source
object
etstring
ne sont pas des types primitifs.Il y a quelques bonnes réponses ci-dessus. Voici une solution tout-en-un. Trois surcharges pour différentes circonstances.
la source
Plutôt que de lancer le vôtre, le moyen le plus fiable de savoir si un type intégré est numérique est probablement de le référencer
Microsoft.VisualBasic
et de l'appelerInformation.IsNumeric(object value)
. L'implémentation gère un certain nombre de cas subtils tels que leschar[]
chaînes HEX et OCT.la source
Il y a trois concepts différents ici:
is
- par exempleif(obj is int) {...}
TryParse()
ToString()
pourrait donner quelque chose qui ressemble à un nombre, appelez-leToString()
et traitez-le comme une chaîneDans les deux premiers cas, vous devrez probablement gérer séparément chaque type numérique que vous souhaitez prendre en charge (
double
/decimal
/int
) - chacun a des plages et une précision différentes, par exemple.Vous pouvez également consulter regex pour une vérification rapide et approximative.
la source
En supposant que votre entrée est une chaîne ...
Il existe 2 façons:
utilisez Double.TryParse ()
utiliser Regex
la source
Vous pouvez utiliser un code comme celui-ci:
Si votre objet est un
Int32
,Single
,Double
etc. , il effectuera la conversion. De plus, une chaîne implémenteIConvertible
mais si la chaîne n'est pas convertible en double, alors unFormatException
sera lancé.la source
Si votre exigence est vraiment
et que vous souhaitez utiliser double.TryParse, vous devez utiliser la surcharge qui prend un paramètre NumberStyles et vous assurer que vous utilisez la culture invariante.
Par exemple, pour un nombre qui peut avoir un signe de début, aucun espace blanc de début ou de fin, aucun séparateur de milliers et un séparateur décimal de période, utilisez:
la source
En écrivant ma propre
object.IsNumeric()
méthode d'extension basée sur la réponse de Saul Dolgin à cette question, j'ai rencontré un problème potentiel en ce que vous obtiendrez unOverflowException
si vous l'essayez avecdouble.MaxValue
oudouble.MinValue
.Ma «solution» a été de combiner la réponse acceptée de Noldorin avec celle de Saul Dolgin et d'ajouter un commutateur de correspondance de modèle avant d'essayer d'analyser quoi que ce soit (et d'utiliser un peu de bonté C # 7 pour ranger un peu):
la source
Oui, cela fonctionne:
Pour un nombre à virgule flottante, vous devrez tester en utilisant le type float:
la source