What is the purpose of the "out" keyword at the caller (in C#)?
Asked Answered
C

8

1

When a C# function has an output parameter, you make that clear as follows:

private void f(out OutputParameterClass outputParameter);

This states that the parameter does not have to be initialized when the function is called. However, when calling this function, you have to repeat the out keyword:

f(out outputParameter);

I am wondering what this is good for. Why is it necessary to repeat part of the function specification? Does anyone know?

Cloutman answered 8/9, 2009 at 13:11 Comment(0)
C
-1

The best answer I got was posted as a comment by plinth:

The most important reason for the repeating of out/ref is that if the function you're calling gets refactored with a different signature, you will get a compile error. Most notably, if a parameter goes from non-out to out, you'll know right away.

Cloutman answered 16/11, 2009 at 10:50 Comment(0)
U
27

It means you know what you're doing - that you're acknowledging it's an out parameter. Do you really want the utterly different behaviour to happen silently? The same is true for ref, by the way.

(You can also overload based on by-value vs out/ref, but I wouldn't recommend it.)

Basically, if you've got an (uncaptured) local variable and you use it as a non-out/ref argument, you know that the value of that variable won't be changed within the method. (If it's a reference type variable then the data within the object it refers to may be changed, but that's very different.)

This avoids the kind of situation you get in C++ where you unknowingly pass something by reference, but assume that the value hasn't changed...

Underthecounter answered 8/9, 2009 at 13:14 Comment(17)
Exactly. It can cause huge headaches if your variable is unconsciously changed by the callee.Missus
Here here! PHP "return by reference" (or passing parameters by reference, same thing) let you ignore the "by reference" by excluding the ampersand at the point of assigning the return value. Talk about an insanely maddening bug to find when all you left out is an ampersand somewhere. Requiring "out" in C# is the sanest way to avoid such bugs.Clemmie
As a curiosity, why is it not recommended to have an overload on out? Does it has an impact on performance, or it is for readability?Ingemar
@Mehrdad: in C# all class instances are passed by reference.Cloutman
"This avoids the kind of situation you get in C++ where you unknowingly pass something by reference": in C++, most function parameters should be marked as "const". In such a case, you are (almost) certain that you variable won't be modified.Cloutman
@Dimitri: No they're not. The reference is passed by value. There's a huge difference. Please read pobox.com/~skeet/csharp/parameters.htmlUnderthecounter
@Dimitri: You only know about the const if you check the signature, in which case you already know it's by-ref.Underthecounter
Dimitri C: To quote Jon: "Objects are not passed at all. References are passed by value."Missus
@Pierre-Alain: Overloading can get confusing enough as it is. Overloading by such a relatively subtle thing as how the parameter is passed is almost bound to cause confusion.Underthecounter
If the "out" keyword needs to be duplicated, wouldn't it be better that you would have to duplicate the parameter types also?Cloutman
@Dimitri: Those are already enforced by the compiler by static typing - the argument type has to be implicitly convertible to the parameter type, or in the case of ref/out they have to be exactly the same type.Underthecounter
The MOST important reason for the repeating of out/ref is that if the function you're calling gets refactored with a different signature, you will get a compile error. Most notably, if a parameter goes from non-out to out, you'll know right away.Aqualung
@Jon, @Dimitri C.: Also, the readers of the calling code may not know about out/ref in the function signature. On the other hand, parameter types will be easily inferred by knowing the types of the actual parameters.Merilee
@plinth: that is a very good remark. I hadn't thought about that! Wouldn't it be better to post that as an answer?Cloutman
In my opinion, if this duplication serves only for clarity, it merely increases verboseness. However, I think plinth's remark is to the point, as it aids refactoring.Cloutman
@Dimitri C. I think it does increase clarity.Merilee
@Dimitri: Bear in mind that this duplication isn't (often) between two bits of code in the same file. It's between a method parameter which you may not even have the source for, and the method argument you happen to be looking at. Personally I like to be able to understand pretty much what code will do without having to look up every signature to check if it has any ref/out parameters.Underthecounter
P
3

It is a design feature. It is clear that it was not necessary, but it aids in readability.

Parlance answered 8/9, 2009 at 13:13 Comment(0)
I
2

While I don't know the origin of such decision, I know that it has a purpose for overloading.

It is totally legal to create these two functions in the same class:

private void f(out OutputParameterClass outputParameter);

and

private void f(OutputParameterClass outputParameter);

Specifying the out keyword when calling such overload make sense.

Ingemar answered 8/9, 2009 at 13:15 Comment(0)
G
2

For readability, knowing what the method can/will do to your variable.

Got some more info from MSDN: http://msdn.microsoft.com/en-us/vcsharp/aa336814.aspx

The caller of a method which takes an out parameter is not required to assign to the variable passed as the out parameter prior to the call; however, the callee is required to assign to the out parameter before returning.

Grof answered 8/9, 2009 at 13:27 Comment(0)
D
1

The only reason I can see is to make sure the user of the function knows that the value of this parameter can be modified by the function. I think it's a good thing.

Devilment answered 8/9, 2009 at 13:14 Comment(5)
Not only it can be modified - it will be modified.Merilee
Daniel: Not really. It can leave the function unmodified. out is enforced by the compiler. If the declaring function is written in another language, it might choose not to enforce definite assignment.Missus
In another language? Which one?Merilee
For example, you craft your own function in IL and decorate it with out attribute. Then you'll have a C# method call it.Missus
How typical :] Well, in any case, the out parameter in C# (which was the question's tag) must be assigned to in the function. Of course you may try to jump around it, but I don't see much sense in using this kind of modifiers (out, ref) without respecting their semantics.Merilee
A
1

I think it's a matter of consistency and clarity.

Clearly, the compiler could do well without. However, with the out keyword added, you're making your intentions clear, and the code gets clearer and more legible.

Advowson answered 8/9, 2009 at 13:15 Comment(0)
C
-1

The best answer I got was posted as a comment by plinth:

The most important reason for the repeating of out/ref is that if the function you're calling gets refactored with a different signature, you will get a compile error. Most notably, if a parameter goes from non-out to out, you'll know right away.

Cloutman answered 16/11, 2009 at 10:50 Comment(0)
E
-2

You probably have to use out for clarity. If you wouldn't know without looking at the method signature.

Efficacy answered 8/9, 2009 at 13:12 Comment(1)
The example you've got doesn't work due to the definite assignment differences between out and ref.Underthecounter

© 2022 - 2024 — McMap. All rights reserved.