2010-08-02 4 views
74

Ich versuche TryParse zu verwenden, um herauszufinden, ob der Zeichenfolgenwert eine Ganzzahl ist. Wenn der Wert eine Ganzzahl ist, überspringen Sie die foreach-Schleife. Hier ist mein Code.Wie int.TryParse mit nullable int verwenden?

intVal ist eine Variable vom Typ int? (Nullable INT). Wie kann ich Tryparse mit Nullable Int verwenden?

Antwort

69

Das geht leider nicht ohne eine andere Variable, da der Typ der out Argumente genau mit dem Parameter übereinstimmen muss.

wie Daniels Code, aber in Bezug auf das zweite Argument festgelegt, Trimmen, und die Vermeidung von Vergleiche mit Booleschen Konstanten:

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

@JonSkeet - strValue kann null sein und die Trim() -Methode würde zu einer Ausnahme führen. Sag es einfach. :) –

+3

@ShaktiPrakashSingh: Wir wissen nicht, ob 'strValue' null sein könnte oder nicht. Wenn es aus einem Textfeld kommt, kann es * wahrscheinlich nicht null sein. Mein Code versucht nicht, dies anzugehen, aber wir wissen wirklich nicht, ob er es * ansprechen sollte oder nicht. –

+0

Warum nicht das 'if' umkehren? zB: 'if (int.TryParse (Request [" idParent "], out tmp)) idParent = tmp;' (sonst ist es null) – Dementic

5

Sie eine Hilfsmethode erstellen kann einen Nullable-Wert zu analysieren.

Verwendungsbeispiel:

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

Helper-Methode:

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

Hier ist eine Option für ein Nullable-int mit TryParse

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

Ich mag diese Version, da" 0 "0 zurückgibt und" Hallo "null zurückgibt. In der angenommenen Antwort ist die Unterscheidung verloren. –

+8

Ich mag seine Antwort nicht, weil sie den Rückgabewert verliert, der den Erfolg/das Fehlschlagen des Parsens anzeigt. Das ist ein wichtiges Merkmal einer Try * -Methode. – frattaro

+1

@frattaro Ich sehe nicht wirklich, warum diese Antwort schlecht sein könnte. Versuchen Sie bei Fehlschlagen die Rückgabe von 0 standardmäßig 0, in diesem Beispiel wird stattdessen nur null zurückgegeben. – Edgar

20

kann mich nicht verhindern, dass eine generische Version zu produzieren. Verwendung unten.

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

Sie könnten auch eine Erweiterungsmethode für diesen Zweck erstellen;

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

Ich habe dies eine Erweiterung auf dem object Typ, aber es könnte genauso gut sein, auf string gemacht. Persönlich mag ich, dass diese Parser-Erweiterungen für jedes Objekt verfügbar sind, daher die Erweiterung object anstelle von string.

Beispiel:

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

Der Nachteil wäre, dass dies mit der Syntax Frameworks bricht Wert für das Parsen;

int.TryParse(input, out output)) 

Aber Ich mag die kürzere Version davon (ob es besser lesbar ist oder nicht könnte Gegenstand von Diskussionen sein);

input.TryParse(out output) 
+0

Wenn Sie dies tun, sind Sie nur in' TryParse' für 'int' gesperrt. Was ist mit "double"? Oder 'bool'? – FMM

+0

@FMM ein bisschen spät, aber schreiben Sie eine separate Erweiterungsmethode für diejenigen, wenn Sie sie wollen. nicht sicher, was du meinst "eingesperrt" die anderen Erweiterungsmethoden würden eine andere Signatur haben –

+0

'T' ist implizit in' T? 'für Strukturen umwandelbar. Das ist Overkill. – FMM

Verwandte Themen