In general, a method's return value as in
bool DoSomething() is the result that is deliberately intended by the programming logic. Put in other words, the return value of a method must represent the purpose of calling that method.
On the other hand, an output
out parameter modifier (there is also a
ref modifier in C#), implies an additional information that is generated during the method execution. This information is not the goal of the method, but still it is necessary to be supplied, because it may be used latter, or because it could be tedious to obtain that information a second time.
For instance, take the
bool int.TryParse(string value) method. It implies that you are interested in checking if
value is an integer, regardless of the actual integer it represents. In other words, you you ask if some string is a number and expect the computer to say: "yes, it is a n integer" or "no, it is not". The
out parameter in this case represents the parsed integer, that is produced only if the parsing was successful.
Consider for instance the following code:
if (int.IsValidInt(value)) // an imaginary method
int theInt = int.Parse(value);
Assume that the
int.IsValidInt(value) method (that does not originally exist in .NET) checks if a string is integer by internally parsing it. It will produce an integer corresponding to the
value parameter, but we will not be able to use it latter. So, if we need it, we will have to parse it again (via the
int.Parsemethod), thus repeating the same operations already done by the
int.IsValidInt alongside all the associated CPU and memory usage.
In such cases (like the one determining if a string represents an integer) we may have to produce a secondary result, that should be used latter. This is a good enough reason to use an an output parameter, as done in the
In regards to choosing which to be the return value, I think it should be the one that best represents the intentions of the method, and any additional data should be supplied as an output parameter.
According to the
int.TryParse question, it depends on your case. If you need to to execute different logic depending on the input being a number or not, the
int.TryParse seems more natural to use as it implies the logical branching:
if (int.TryParse(input, out parsed))
int importantCalculation = parsed*someMagicNumber;
/// other business logic
// ask for input again
In case you need to operate with the input, you have a choice:
int.Parse(input); directly. This will cause an exception if the input is not valid, and you may have to handle the exception using
try-catch blocks. Do this, if you need to show the user information for the error, or if invalid integers are unacceptable in this case.
int.TryParse in combination with
else. This can be useful if you need faster code (exception slow down the runtime), or if you have an alternative logic flow that can be executed.