Why does the "out" parameter exist in C# as a language construct?
Elaboration on the question
Why does it exist in the first place? Aren't there better language features to get the same effect one can get with the "out" parameter?
Isn't it strange to make an value type behave like a reference type?
Aren't there better ways to return multiple values from a method?
Is it a historical thing, meaning with the first versions of C# there was no way to achieve the things one can achieve with the out parameter but now there are newer features and it's just kept in the language for backwards compatibility?
What I'm not asking
- I'm not asking what it does
- I'm not asking how it is used
- I'm not asking what the difference between "ref" and "out" is
- I read that one should avoid its use and choose other constructs
I haven't found any duplicates while reading the similar questions.
Expected answer format
I'd love to hear something like, "Look, here is a problem you can only solve with the use of the "out" parameter language construct and here is a code example for it...".
Or, "Look, this used to be the only way to solve the following problem ...code example..., but since C# version ... the better way to solve is like this ... code example...".
No opinions please.
The C# compiler performs definite assignment checking. That requires it to know exactly when a variable is assigned. Usually not hard to figure out, an assignment is pretty easy to see back.
But there is a corner-case is when a variable is passed by reference to another method. Does the method require that variable to be assigned before the call, then modifies it, or is it only ever going to assign it? The compiler in general cannot know, the method may live in another assembly with the method body unavailable. True for any .NET Framework assembly for example.
So you have to be explicit about it, you use
ref when the method requires the parameter to be assigned before the call,
out when the method only ever assigns it. Great feature btw, it eliminates an entire swath of very common bugs.
One note about other incorrect answers on this question. Data flow plays an important role in pinvoke as well, the pinvoke marshaller needs to know whether the convert any data returned by an unmanaged function. It does not pay attention to out vs ref keywords, only to the
[Out] attributes. More about that gritty detail in this Q+A.