I am seeing lots of these in a method in our code:
int num1 = 0;
if (Char.IsDigit(myStr[2]) && Int32.TryParse(myStr[2].ToString(), out num1) == false)
{
valid = false;
}
So are they just making sure the third character us a digit?
I am seeing lots of these in a method in our code:
int num1 = 0;
if (Char.IsDigit(myStr[2]) && Int32.TryParse(myStr[2].ToString(), out num1) == false)
{
valid = false;
}
So are they just making sure the third character us a digit?
The code shown parses the 3rd character only - checking if it is digit, then parsing the string representation of that single character. Instead, just use the numeric value of that character:
if(myStr[2] >= '0' && myStr[2] <= '9') {
num1 = (int)myStr[2] - (int)'0';
} else {
valid = false
}
You can safely skip the IsDigit()
check as it's redundant.
TryParse()
will fail if it's not a digit.
As it has been pointed out by others, Char.IsDigit()
is quicker. If your code is performance sensitive the check makes sense.
If you leave the IsDigit
check in place, then you can reduce TryParse
to Int32.Parse()
as at that point the parsing won't fail.
It looks like the code that you have is doing this for efficiency. Whoever coded this, knows the structure of the string in myStr
to sometimes have a non-numeric symbol in the third position. That's why he made this optimization to check the third symbol before paying for the conversion of the character array to string which then gets parsed.
Chances are, this optimization is premature: although making a temporary throw-away string is not free, this optimization would make sense only in situations when you do it a lot in a very tight loop. In other words, you do it only if it shows up near the top in your performance profiler's output.
You can optimize this check to avoid if
:
int num1 = 0;
valid &= !Char.IsDigit(myStr[2]) || Int32.TryParse(myStr[2].ToString(), out num1);
I don't believe you need the first part (it could also throw an IndexOutOfRangeException
).
So I would probably use:
int num1 = 0;
if (myStr.Length > 2 && Int32.TryParse(myStr[2].ToString(), out num1) == false)
{
valid = false;
}
Char.IsDigit Method (String, Int32)
Indicates whether the character at the specified position in a specified string is categorized as a decimal digit.
Int32.TryParse Method
Converts the string representation of a number to its 32-bit signed integer equivalent. A return value indicates whether the operation succeeded. This member is overloaded.
First I wrote that you can skip any of the check but now I am writing that you can not because
if (Char.IsDigit(myStr[2]) && Int32.TryParse(myStr[2].ToString(), out num1) == false)
{ }
Char.IsDigit()
will return true
if myStr[2]
contains any of the Unicode characters listed here but Int.TryParse()
will not convert any numbers except for 0-9 (not sure about this, as I have not checked all of them) so it will return false
which is you are checking...
The condition you are checking can be understood by the following example:
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
answer is the best solution for checking this condition...
Here's how I'd write it:
int num1 = 0;
try
{
num1 = Int32.Parse(myStr[2].ToString());
}
catch (Exception)
{
valid = false;
}
This does the same thing and is a lot easier to read imho, oh & you can log failed parses inside the catch.
Or you can do:
int num1 = 0;
valid = Int32.TryParse(myStr[2].ToString(), out num1);