Sure, take a look at any of the TryParse
methods, such as int.TryParse
:
The idea is you actually want two pieces of information: whether a parse operation was successful (the return value), and, if so, what the result of it actually was (the out
parameter).
Usage:
string input = Console.ReadLine();
int value;
// First we check the return value, which is a bool
// indicating success or failure.
if (int.TryParse(input, out value))
{
// On success, we also use the value that was parsed.
Console.WriteLine(
"You entered the number {0}, which is {1}.",
value,
value % 2 == 0 ? "even" : "odd"
);
}
else
{
// Generally, on failure, the value of an out parameter
// will simply be the default value for the parameter's
// type (e.g., default(int) == 0). In this scenario you
// aren't expected to use it.
Console.WriteLine(
"You entered '{0}', which is not a valid integer.",
input
);
}
Many developers complain of out
parameters as a "code smell"; but they can be by far the most appropriate choice in many scenarios. One very important modern example would be multithreaded code; often an out
parameter is necessary to permit "atomic" operations where a return value would not suffice.
Consider for example Monitor.TryEnter(object, ref bool)
, which acquires a lock and sets a bool
atomically, something that wouldn't be possible via a return value alone since the lock acquisition would necessarily happen before the return value were assigned to a bool
variable. (Yes, technically ref
and out
are not the same; but they're very close).
Another good example would be some of the methods available to the collection classes in the System.Collections.Concurrent
namespace new to .NET 4.0; these provide similarly thread-safe operations such as ConcurrentQueue<T>.TryDequeue(out T)
and ConcurrentDictionary<TKey, TValue>.TryRemove(TKey, out TValue)
.