I am in favor of using an output parameter. In my opinion, this is the kind of situation for which use of an output parameters is most suited.
Yes, you can use the coalesce operator to keep your code as a one-liner if and only if you have an alternative value that you can use in the rest of your code. I often find that is not the case for me, and I would prefer to execute a different code path than I would if I was successfully able to retrieve a value.
int value;
if(DoSomethingWonderful(out value))
{
// continue on your merry way
}
else
{
// oops
Log("Unable to do something wonderful");
if (DoSomethingTerrible(out value))
{
// continue on your not-so-merry way
}
else
{
GiveUp();
}
}
Additionally, if the value that I want to retrieve is actually nullable, then using a function with an output parameter and a boolean return value is, in my opinion, the easiest way to tell the difference between "I was unsuccessful in retrieving the value" and "The value I retrieved is null". Sometimes I care about that distinction, such as in the following example:
private int? _Value;
private bool _ValueCanBeUsed = false;
public int? Value
{
get { return this._Value; }
set
{
this._Value = value;
this._ValueCanBeUsed = true;
}
}
public bool DoSomethingTerrible(out int? value)
{
if (this._ValueCanBeUsed)
{
value = this._Value;
// prevent others from using this value until it has been set again
this._ValueCanBeUsed = false;
return true;
}
else
{
value = null;
return false;
}
}
In my opinion, the only reason most people tend not to use output parameters is because they find the syntax cumbersome. However, I really feel that using output parameters is the more appropriate solution to this problem, and I found that once I got used to it I found the syntax much preferable to returning a null value.