2014-10-10 3 views
4

Я вижу много из них в методе в нашем коде:Легче способ проверки Int32.TryParse

int num1 = 0; 
if (Char.IsDigit(myStr[2]) && Int32.TryParse(myStr[2].ToString(), out num1) == false) 
{ 
    valid = false; 
} 

Так они просто убедившись, что третий символ нам цифру?

+0

Может быть, я что-то очевидное отсутствует, но я не могу работать, какое значение для 'myStr [2]' 'вызовет Char.IsDigit (myStr [2]) ', чтобы быть истинным, и' Int32.TryParse (myStr [2] .ToString(), out num1) 'будет false. И.Е. Это цифра от 0 до 9, но не может быть проанализирована как целое число. –

+0

@BenRobinson см. Ответы – thumbmunkeys

+0

Каков тип 'myStr'? это «строка»? –

ответ

4

Похоже, что код, который у вас есть, делает это для эффективности. Кто бы ни закодировал это, знает структуру строки в myStr, чтобы иногда иметь нечисловой символ в третьей позиции.Именно поэтому он сделал эту оптимизацию, чтобы проверить третий символ, прежде чем платить за преобразование массива символов в строку, которая затем анализируется.

Скорее всего, эта оптимизация преждевременна: хотя временная отбрасываемая строка не является бесплатной, эта оптимизация будет иметь смысл только в ситуациях, когда вы делаете это много в очень плотной петле. Другими словами, вы делаете это только в том случае, если он отображается вверху в выводе профилировщика производительности.

Вы можете оптимизировать эту проверку, чтобы избежать if:

int num1 = 0; 
valid &= !Char.IsDigit(myStr[2]) || Int32.TryParse(myStr[2].ToString(), out num1); 
5

Вы можете смело пропустить проверку IsDigit(), поскольку она является избыточной.

TryParse() не работает, если это не цифра.

Как было указано другими, Char.IsDigit() быстрее. Если ваш код чувствителен к производительности, проверка имеет смысл.

Если вы оставите IsDigit чек на месте, вы можете уменьшить TryParse до Int32.Parse(), так как в этот момент разбор не подведет.

+0

Может быть, TryParse' является частью избыточности, особенно если вы не используете 'num1' для чего-либо. – Matthew

+0

@Matthew: Это большое предположение из всего лишь одного фрагмента кода. –

+1

@Matthew да, может быть. Я не могу сказать из контекста. – thumbmunkeys

3

Я не верю, что вам нужна первая часть (она также может выбрасывать IndexOutOfRangeException).

Так что я бы, вероятно, использовать:

int num1 = 0; 
if (myStr.Length > 2 && Int32.TryParse(myStr[2].ToString(), out num1) == false) 
{ 
    valid = false; 
} 
1

Char.IsDigit метод (String, Int32)

Указывает, является ли символ в указанной позиции в указанной строке классифицируется как десятичного знака ,

Link

Int32.TryParse Метод

Преобразует строковое представление числа его 32-битовое целое число эквивалент. Возвращаемое значение указывает, была ли операция успешной. Этот член перегружен.

Link

Edit:

Сначала я писал, что вы можете пропустить любую из проверки, но теперь я пишу, что вы не можете, потому что

if (Char.IsDigit(myStr[2]) && Int32.TryParse(myStr[2].ToString(), out num1) == false) 
{ } 

Char.IsDigit() вернется true если myStr[2] содержит любой из символов Юникода, перечисленных here, но Int.TryParse() не преобразует никакие числа, кроме 0-9 (не уверен в этом, так как у меня есть не проверил все из них), так что он будет возвращать false, который вы проверяете ...

условие вы проверяете можно понять на следующем примере:

string x = "AS௭s"; 
int s = 0; 
if (Char.IsDigit(x[2]) && int.TryParse(x[2].ToString(), out s) == false) 
{ 
    // even if '௭` is Tamil Digit Seven and 'Char.IsDigit()' will return true but 
    // int.TryParse() will return false because it can not convert it 
    // so you are setting valid = false when the myStr contains a valid Unicode Character 
    // for a digit but It can not be converted to integer by TryParse method... 
    valid = false; 
} 

@Marc Gravell♦'s ответ является лучшим решением для проверяя это условие ...

-3

Вот как я бы писать:

int num1 = 0; 
try 
{ 
    num1 = Int32.Parse(myStr[2].ToString()); 
} 
catch (Exception) 
{ 
    valid = false; 
} 

Это делает то же самое, и это намного проще читать имхо, о & вы можете записывать неудачные разборки внутри улова.

Или вы можете сделать:

int num1 = 0; 
valid = Int32.TryParse(myStr[2].ToString(), out num1); 
+1

Это безоговорочно изменит 'valid', в то время как исходный пример сохранит старое значение, когда третий символ не является цифрой. Кроме того, «TryParse» был введен, чтобы помочь вам избежать использования более дорогого 'try' /' catch' в вашем коде. – dasblinkenlight

+0

Я предполагаю, что нам нужно знать намерение за действительным, поскольку 99% сценариев, действующих для истины при успехе, совершенно законны и не связаны с дублированием логической логики. Попробуйте поймать более дорогой уверен (никто бы никогда не заметил, что я держал пари), но, как я сказал в своем ответе, это больше для удобочитаемости. – RandomUs1r

+0

Как правило, вы никогда не должны использовать исключения для потока программы. – thumbmunkeys

7

Код, показанный разбирает 3-го символа только - проверка, если это цифра, то разбор строковое представление этого одного символа. Вместо этого просто использовать численное значение этого символа:

if(myStr[2] >= '0' && myStr[2] <= '9') { 
    num1 = (int)myStr[2] - (int)'0'; 
} else { 
    valid = false 
} 
+0

Я думаю, что это самый простой способ проверить в этой ситуации ... –

+2

Я бы даже зашел далеко, чтобы сказать, что это, скорее всего, самый быстрый (игнорируя возможное исключение OutOfRangeException). –

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