2011-01-06 2 views
33

int.TryPrase велик, и все, но есть только одна проблема ... она занимает по меньшей мере, две строки кода для использования:int.TryParse облегченная запись

int intValue; 
string stringValue = "123"; 
int.TryParse(stringValue, out intValue); 
.... 

Конечно, я могу сделать что-то вроде:

string stringValue = "123"; 
int intValue = Convert.ToInt32(string.IsNullOrWhiteSpace(stringValue) ? 0 : stringValue); 

только на одной строке кода.

Как я могу выполнить некоторую магию, чтобы получить int.TryParse, чтобы использовать один лайнер, или есть еще третья альтернатива?

Спасибо!

Bezden ответил на вопрос лучше, но на самом деле я планирую использовать решение Reddogs.

+0

Хотя немного поздно к этой партии ... Я полностью согласен, что было бы неплохо иметь TryParse как один лайнер, но предложения здесь не очень приятно. В C# 6.0 было предложено языковое предложение, которое позволило бы использовать этот синтаксис ... bool result = int.TryParse ("123", out int value); // value = 123 – series0ne

+0

related: если вы выполняете int до int? вы можете сделать 'int.TryParse (« string », out int result)? result: result', поэтому компилятор не разозлится – smurtagh

ответ

53
int intValue = int.TryParse(stringValue, out intValue) ? intValue : 0; 
+8

Nice. Единственная проблема, конечно, в том, что вы не можете отличить плохое значение от 0 во входной строке ... это забирает точку использования TryParse() –

+1

Nice. Я могу выкопать его. –

+0

вы избили меня до этого :). +1 для того же решения :) –

0

Я не думаю, что есть что-то очень красиво, но если вы, как это вы получите его до одной строки:

string stringValue = "123" 
int intValue = int.TryParse(stringValue, out intValue) ? intValue : 0; 
37

Возможно использовать метод расширения:

public static class StringExtensions 
{ 
    public static int TryParse(this string input, int valueIfNotConverted) 
    { 
     int value; 
     if (Int32.TryParse(input, out value)) 
     { 
      return value; 
     } 
     return valueIfNotConverted; 
    } 
} 

И использование:

string x = "1234"; 
int value = x.TryParse(0); 

Редактировать: И, конечно, вы можете добавить очевидную перегрузку, которая уже устанавливает значение по умолчанию равным нулю, если это ваше желание.

+1

+1 Возможно, вы захотите включить использование 'int x =" 123 ".TryParse (1);' –

+0

Я хотел добавить то же самое решение, что и выше, с помощью int num = "123" .ToInt(); но вы были быстрее! за это получите +1 – Delashmate

1

Вы не хотите делать int.TryParse() в одной строке. Зачем? Поскольку вы не можете назначить intValue, если строка ввода не является допустимым целым числом. Вся точка TryParse() - это позволить вам проверить хороший ввод и грамотно деградировать, вместо того, чтобы поймать исключение.

Int.TryParse() уже является ярлыком, поэтому вам не нужно тестировать действительный int и выполнять задание в два этапа ... это насколько вы хотите его принять.

+0

Спасибо, но я не согласен со всеми вашими очками. Они просто неправды. –

+3

Достаточно справедливо:) –

0

Поскольку он по существу возвращает два значения (успех и значение), нам действительно нужны две строки.

Вы могли бы попробовать класс-оболочку, то есть:

void Main() 
{ 
    var result = simpleIntParser.TryParse("1"); 
    if(result) 
    { 
     Console.WriteLine((int)result); 
    } else { 
     Console.WriteLine("Failed"); 
    } 

    result = simpleIntParser.TryParse("a"); 
    if(result) 
    { 
     Console.WriteLine((int)result); 
    } else { 
     Console.WriteLine("Failed"); 
    } 


} 

public class simpleIntParser 
{ 
    public bool result {get; private set;} 
    public int value {get; private set;} 

    private simpleIntParser(bool result, int value) 
    { 
     this.result = result; 
     this.value = value; 
    } 

    public static simpleIntParser TryParse(String strValue) 
    { 
     int value; 
     var result = int.TryParse(strValue, out value); 
     return new simpleIntParser(result, value); 
    } 

    public static implicit operator int(simpleIntParser m) 
    { 
     return m.value; 
    } 

    public static implicit operator bool(simpleIntParser m) 
    { 
     return m.result; 
    } 
} 

Это требует литье, если тип неоднозначен (т.е. для Console.WriteLine()), но если передать его в качестве параметра целого числа, например, литье не требуется

+0

Whoa whoaaaaa, подождите, что такое .Dump()? –

+0

Это из linqPad, извините. Он просто печатает его на экране. – Rob

3

Я бы создал метод расширения из этого.

public static int? AsInt32(this string s) 
    { 
     int value; 
     if (int.TryParse(s, out value)) 
      return value; 

     return null; 
    } 
+0

Это лучшее решение здесь, потому что в одной строке мы получаем успешное синтаксическое значение, и мы все еще можем различать строку, которая не анализируется, и строка «0» –

1

Проверьте класс StringExtensions. Он содержит метод расширения AsInt(String,Int32), который будет пытаться преобразовать строку, и если неуспешно заполнить ее с указанным значением Int32 по умолчанию.

Пример:

var intValue = "123".AsInt(-1); 
+0

У меня нет этого метода, доступного по умолчанию?! (.net Framework 4.5) – Muflix

0
int val2 = "asd".AsInt(-1); 
//Output : -1 
int val3 = "123".AsInt(-1); 
//Output : 123 

Вы должны иметь System.Web.WebPages имен.

1

Этот ответ предназначен только для тех, кто использует не менее C# 7.

Теперь вы можете объявить параметр out inline.

int.TryParse("123", out var result); 

Чтобы доказать это, вы можете запустить следующую dotnetfiddle.

int.TryParse("123", out var result); 
Console.WriteLine(result); 
Console.WriteLine(result.GetType()); 

https://dotnetfiddle.net/nn9955

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