Microsoft's documentation for the out
parameter modifier points out the following:
Declaring a method with
out
arguments is a classic workaround to return multiple values. Consider value tuples for similar scenarios.
This strikes me as a remarkably good point. What use case remains for out
, now that we have value tuples?
One major use case I can think of off the top of my head are Try...
methods that return a value and a boolean so that you can check whether the action succeded or not:
// With out parameters:
if(int.TryParse(someString, out int result)){
// do something with the int
}
// With tuples:
var (success, value) = int.TryParseWithTuples(someString);
if(success){
// do something with the int
}
With the out
parameter, the notation is cleaner and results in less lines (and doesn't require you to create a local variable for the success boolean). It also allows you to do this:
if(int.TryParse(someString, out int r1)){
// do something with the int
} else if(int.TryParse(fallbackString, out int r2)){
// do something with the fallback int
} else {
throw new InvalidOperationException();
}
With tuples, this would look like this:
var (success, value) = int.TryParseWithTuples(someString);
if(success){
// do something with the int
} else {
(success, value) = int.TryParseWithTuples(fallbackString);
if(success){
// do something with the fallback int
} else {
throw new InvalidOperationException();
}
}
In addition to the ease of use of the TryX
pattern, as pointed out by ascpixi, another case that makes a value-tuple unsuitable as a return type is when one of the two values is a reference. For example take a look at the CollectionsMarshal.GetValueRefOrAddDefault
API:
public static ref TValue? GetValueRefOrAddDefault<TKey,TValue> (
Dictionary<TKey,TValue> dictionary,
TKey key,
out bool exists);
It is used like this:
ref int refValue = ref CollectionsMarshal.GetValueRefOrAddDefault(
dictionary, key, out bool exists);
if (!exists) refValue = 1; else refValue++;
The ValueTuple<T1, T2>
is not a ref struct
, so it could not be used for this API. Theoretically this API could return a custom tuple-like ref struct
, but in that case it would lack the language support that exists only for real value-tuples, like the shorthand notation with parentheses etc.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With