2010-08-02 2 views
74

Я пытаюсь использовать TryParse, чтобы узнать, является ли строковое значение целым числом. Если значение является целым числом, пропустите цикл foreach. Вот мой код.Как использовать int.TryParse с nullable int?

string strValue = "42 " 

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

intVal - это переменная типа int? (Значение NULL INT). Как я могу использовать Tryparse с nullable int?

ответ

69

Вы не можете сделать это, не используя другую переменную, к сожалению, потому что аргументы out должны точно соответствовать параметру.

Как код Даниила, но фиксированы с точкой зрения второго аргумента, зачисткой и избежать сравнений с булевыми константами:

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

@JonSkeet - strValue cna be null, а метод Trim() приведет к исключению. Просто говорю. :) –

+3

@ShaktiPrakashSingh: Мы не знаем, может ли 'strValue' быть нулевым или нет. Если он исходит из текстового поля, он, вероятно, * не может * быть нулевым. Мой код не пытается решить эту проблему, но мы действительно не знаем, должен ли он * указывать его. –

+0

Почему бы не обратить вспять 'if'? например: 'if (int.TryParse (Request [" idParent "], out tmp)) idParent = tmp;' (в противном случае его значение null) – Dementic

5

Вы можете создать вспомогательный метод для разбора обнуляемого значения.

Пример:

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

Helper Метод:

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

Вот вариант для обнуляемого междунар с TryParse

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

Мне нравится эта версия, так как« 0 »возвращает 0, а« hello »возвращает null. В принятом ответе различие теряется. –

+8

Мне не нравится его ответ, потому что он теряет возвращаемое значение, указывающее на успех/неудачу анализа. Это важная функция метода Try *. – frattaro

+1

@frattaro Я действительно не понимаю, почему этот ответ может быть плохим. Попробуйте parse возвращает 0 по умолчанию при ошибке, в этом примере он просто возвращает null вместо этого. – Edgar

20

Не удалось предотвратить себя производить общую версию. Использование ниже.

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

Вы также можете сделать способ расширения для этой цели;

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

Я сделал это расширение на object типа, но он может одинаково хорошо быть на string. Лично мне нравятся эти расширители парсеров, чтобы быть доступными на любом объекте, следовательно, расширение на object вместо string.

Пример использования:

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

Минусом будет то, что это нарушает с синтаксисом рамок для разбора значений;

int.TryParse(input, out output)) 

Но мне нравится сокращенный вариант этого (будь то более удобным для чтения или не может быть предметом обсуждения);

input.TryParse(out output) 
+0

Если вы сделаете это, вы будете заблокированы только в' TryParse' для 'int'. Как насчет «двойной»? Или 'bool'? – FMM

+0

@FMM немного поздно, но напишите отдельный метод расширения для тех, кто хочет их. не уверен, что вы имеете в виду «запертый», другие методы расширения будут иметь другую подпись. –

+0

'T' неявно конвертируется в' T? 'для structs. Это излишество. – FMM

Смежные вопросы