2010-08-02 2 views
74

J'essaye d'employer TryParse pour trouver si la valeur de chaîne est un nombre entier. Si la valeur est un entier, ignorez la boucle foreach. Voici mon code.Comment utiliser int.TryParse avec nullable int?

string strValue = "42 " 

if (int.TryParse(trim(strValue) , intVal)) == false 
{ 
    break; 
} 

intVal est une variable de type int? (Nullable INT). Comment puis-je utiliser Tryparse avec null int?

Répondre

69

Vous ne pouvez pas faire cela sans utiliser une autre variable, malheureusement - parce que le type d'arguments out doit correspondre exactement au paramètre.

Comme le code de Daniel, mais fixe en termes de second argument, le parage et éviter des comparaisons avec des constantes booléennes:

int tmp; 
if (!int.TryParse(strValue.Trim(), out tmp)) 
{ 
    break; 
} 
intVal = tmp; 
+0

@JonSkeet - strValue cna être null et la méthode Trim() entraînerait une exception. Je dis juste. :) –

+3

@ShaktiPrakashSingh: Nous ne savons pas si 'strValue' pourrait être nul ou non. Si elle provient d'une zone de texte, elle ne peut probablement pas être nulle. Mon code n'essaie pas de résoudre ce problème, mais nous ne savons vraiment pas s'il doit * ou non * l'adresser. –

+0

pourquoi ne pas inverser le 'if'? Par exemple: 'if (int.TryParse (Demande [" idParent "], out tmp)) idParent = tmp;' (sinon sa valeur nulle) – Dementic

5

Vous pouvez créer une méthode d'aide pour analyser une valeur nullable.

Exemple d'utilisation:

int? intVal; 
if(!NullableInt.TryParse("42", out intVal)) 
{ 
    break; 
} 

Aide Méthode:

public static class NullableInt 
{ 
    public static bool TryParse(string text, out int? outValue) 
    { 
     int parsedValue; 
     bool success = int.TryParse(text, out parsedValue); 
     outValue = success ? (int?)parsedValue : null; 
     return success; 
    } 
} 
101

est ici une option pour un nullable int avec TryParse

public int? TryParseNullable(string val) 
{ 
    int outValue; 
    return int.TryParse(val, out outValue) ? (int?)outValue : null; 
} 
+3

J'aime cette version car" 0 "renvoie 0 et" bonjour "renvoie null. Dans la réponse acceptée, la distinction est perdue. –

+8

Je n'aime pas sa réponse car elle perd la valeur de retour indiquant le succès/l'échec de l'analyse. C'est une caractéristique importante d'une méthode Try *. – frattaro

+1

@frattaro Je ne vois pas vraiment pourquoi cette réponse pourrait être mauvaise. Try parse renvoie 0 par défaut en cas d'échec, dans cet exemple, il renvoie simplement null à la place. – Edgar

20

ne pouvais pas me empêcher de produire une version générique. Utilisation ci-dessous.

public class NullableHelper 
    { 
     public delegate bool TryDelegate<T>(string s, out T result); 

     public static bool TryParseNullable<T>(string s, out T? result, TryDelegate<T> tryDelegate) where T : struct 
     { 
      if (s == null) 
      { 
       result = null; 
       return true; 
      } 

      T temp; 
      bool success = tryDelegate(s, out temp); 
      result = temp; 
      return success; 
     } 

     public static T? ParseNullable<T>(string s, TryDelegate<T> tryDelegate) where T : struct 
     { 
      if (s == null) 
      { 
       return null; 
      } 

      T temp; 
      return tryDelegate(s, out temp) 
         ? (T?)temp 
         : null; 
     } 
    } 


bool? answer = NullableHelper.ParseNullable<bool>(answerAsString, Boolean.TryParse); 
3

Vous pouvez également créer une méthode d'extension à cette fin.

public static bool TryParse(this object value, out int? parsed) 
{ 
    parsed = null; 
    try 
    { 
     if (value == null) 
      return true; 

     int parsedValue; 
     parsed = int.TryParse(value.ToString(), out parsedValue) ? (int?)parsedValue : null; 
     return true; 
    } 
    catch (Exception) 
    { 
     return false; 
    } 
} 

J'ai fait cette extension du type object, mais il pourrait tout aussi bien être sur string. Personnellement, j'aime que ces extensions d'analyseur soient disponibles sur n'importe quel objet d'où l'extension sur object au lieu de string.

Exemple d'utilisation:

[TestCase("1", 1)] 
[TestCase("0", 0)] 
[TestCase("-1", -1)] 
[TestCase("2147483647", int.MaxValue)] 
[TestCase("2147483648", null)] 
[TestCase("-2147483648", int.MinValue)] 
[TestCase("-2147483649", null)] 
[TestCase("1.2", null)] 
[TestCase("1 1", null)] 
[TestCase("", null)] 
[TestCase(null, null)] 
[TestCase("not an int value", null)] 
public void Should_parse_input_as_nullable_int(object input, int? expectedResult) 
{ 
    int? parsedValue; 

    bool parsingWasSuccessfull = input.TryParse(out parsedValue); 

    Assert.That(parsingWasSuccessfull); 
    Assert.That(parsedValue, Is.EqualTo(expectedResult)); 
} 

L'inconvénient serait que cela rompt avec la syntaxe des cadres pour les valeurs de l'analyse;

int.TryParse(input, out output)) 

Mais j'aime la version plus courte de celui-ci (si elle est plus lisible ou non peut être sujet à discussion);

input.TryParse(out output) 
+0

Si vous faites cela, vous êtes verrouillé dans' TryParse' pour 'int' seulement. Qu'en est-il de «double»? Ou 'bool'? – FMM

+0

@FMM un peu en retard mais, écrivez une méthode d'extension séparée pour ceux si vous les voulez. pas sûr de ce que vous voulez dire "verrouillé" les autres méthodes d'extension auraient une signature différente –

+0

'T' est implicitement convertible en' T? 'pour les structures. C'est exagéré. – FMM

Questions connexes