Why does the "out" parameter exist in C# as a language construct?

Viewed 392

Question

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

  1. I'm not asking what it does
  2. I'm not asking how it is used
  3. I'm not asking what the difference between "ref" and "out" is
  4. 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.

3 Answers

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 [In] and [Out] attributes. More about that gritty detail in this Q+A.

One reason would be for compatibility with e.g. Win32 APIs. Some method declarations for Win32 API calls will require the use of out and/or ref if you want to call them directly from C#.

You can find some examples of such method declarations at pinvoke.net: http://pinvoke.net/search.aspx?search=out&namespace=[All]

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?

Whats "better"? Arguing based on C#7 where things are a bit easier, is this:

public static (bool Succesful, int Value) TryParse(string s) { ... }

var parseResult = TryParse(s);
if (parResult.Succesful)
    DoSomething(parResult.Result);

better than?

if (int.TryParse(s, out var i))
    DoSomething(i);

Hmmm....

And before native tuple suport, you'd actually have to implement a struct/class to be able to return multiple values.... yuck. True that the out solution wouldn't be as clean either, but still a better option than having to litter your code base with tons of lightweight container classes to simply have methods return multiple values.

Isn't it strange to make an value type behave like a reference type?

Why? Even if its only for backwards compatibility or for interop, its a needed language feature.

Aslo, your mixing up things here. If you want pass by reference semantics, you'd use the ref keyword. The out keyword means that the parameter is meant to be used as a return value; the fact that it needs to be passed by reference is an implementation detail.

Aren't there better ways to return multiple values from a method?

This is basically your first question rewritten.

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?

Backward compatibility is the obvious and important reason. Also, just because there are better ways to do things doesn't necessarily mean that language features should be removed. You could then make a case for many other language constructs: for loops, goto, etc.

Related