I wanted to revisit my post about the Command-Query Separation Principle.
One of the new Int32 methods is the TryParse method. Essentially, it returns a boolean as to whether a string can be successfully converted to an integer. In addition, if the string can be successfully converted to an integer, it also returns the value.
int returnValue;
bool successful = Int32.TryParse(inputString, out retValue);
If you think about this Int32.TryParse statement, you are commanding it to do something as well as querying it for some information. You are asking it if “inputString“ can be converted to a valid integer, and if so, telling it to parse “inputString” and give you the integer in “retValue“.
Although everyone and their brother can follow this, this type of coding can cause ambiguity while reading code as well as make things a bit more complicated during the refactoring process. Here is a more detailed example:
public void DoIt (string myArgument)
{
// Input Validation
if (string.IsNullOrEmpty(myArgument))
throw new ArgumentNullException("...");
int retValue;
if (!Int32.TryParse(myArgument, out retValue))
throw new ArgumentException(“...“);
// Input Processing
...
}
The method above does basic input validation before processing the input. However, the coder decided to save a step using the Int32.TryParse method and combine input validation with input processing. As developers we now have to realize that if we decide to extract the input validation for some reason, we have to leave the command part of the TryParse method (i.e. Parse) inside this method or we will break the logic.
Hence, in my opinion, better to avoid Int32.TryParse and use the IsNumeric and Parse methods of Int32 to maintain the Command-Query Separation Principle:
public void DoIt (string myArgument)
{
// Input Validation
if (string.IsNullOrEmpty(myArgument))
throw new ArgumentNullException("...");
if (!Int32.IsNumeric(myArgument))
throw new ArgumentException(“...“);
// Input Processing
int retValue = Int32.Parse(myArgument);
...
}
Now, if we want to extract the input validation, we can do it without worrying as much about the input processing. We have separated the Int32.TryParse method into its command and query methods which makes the code much more readable and makes it easier to refactor later. I know this is subtle and probably making a mountain out of a mole hill in this example, but if one follows this principle throught the entire application, maintenance is much, much easier in the future.