When should I use out parameters?

C#.NetOut

C# Problem Overview


I don't understand when an output parameter should be used, I personally wrap the result in a new type if I need to return more than one type, I find that a lot easier to work with than out.

I have seen method like this,

   public void Do(int arg1, int arg2, out int result)

are there any cases where that actually makes sense?

how about TryParse, why not return a ParseResult type? or in the newer framework return a null-able type?

C# Solutions


Solution 1 - C#

Out is good when you have a TryNNN function and it's clear that the out-parameter will always be set even if the function does not succeed. This allows you rely on the fact that the local variable you declare will be set rather than having to place checks later in your code against null. (A comment below indicates that the parameter could be set to null, so you may want to verify the documentation for the function you're calling to be sure if this is the case or not.) It makes the code a little clearer and easier to read. Another case is when you need to return some data and a status on the condition of the method like:

public bool DoSomething(int arg1, out string result);

In this case the return can indicate if the function succeeded and the result is stored in the out parameter. Admittedly, this example is contrived because you can design a way where the function simply returns a string, but you get the idea.

A disadvantage is that you have to declare a local variable to use them:

string result;
if (DoSomething(5, out result))
    UpdateWithResult(result);

Instead of:

UpdateWithResult(DoSomething(5));

However, that may not even be a disadvantage, it depends on the design you're going for. In the case of DateTime, both means (Parse and TryParse) are provided.

Solution 2 - C#

Well as with most things it depends. Let us look at the options

  • you could return whatever you want as the return value of the function
  • if you want to return multiple values or the function already has a return value, you can either use out params or create a new composite type that exposes all these values as properties

In the case of TryParse, using an out param is efficient - you dont have to create a new type which would be 16B of overhead (on 32b machines) or incur the perf cost of having them garbage collected post the call. TryParse could be called from within a loop for instance - so out params rule here.
For functions that would not be called within a loop (i.e. performance is not a major concern), returning a single composite object might be 'cleaner' (subjective to the beholder). Now with anonymous types and Dynamic typing , it might become even easier.

Note:

  1. out params have some rules that need to be followed i.e. the compiler will ensure that the function does initialize the value before it exits. So TryParse has to set the out param to some value even if parse operation failed
  2. The TryXXX pattern is a good example of when to use out params - Int32.TryParse was introduced coz people complained of the perf hit of catching exceptions to know if parse failed. Also the most likely thing you'd do in case parse succeeded, is to obtain the parsed value - using an out param means you do not have to make another method call to Parse

Solution 3 - C#

I think out is useful for situations where you need to return both a boolean and a value, like TryParse, but it would be nice if the compiler would allow something like this:

bool isValid = int.TryParse("100", out int result = 0);

Solution 4 - C#

Years late with an answer, I know. out (and ref as well) is also really useful if you do not wish your method do instantiate a new object to return. This is very relevant in high-performance systems where you want to achieve sub microsecond performance for your method. instantiating is relatively expensive seen from a memory access perspective.

Solution 5 - C#

Definitely, out parameters are intended to be used when you have a method that needs to return more than one value, in the example you posted:

public void Do(int arg1, int arg2, out int result)

It doesn't makes much sense to use an out parameter, since you are only returning one value, and that method could be used better if you remove the out parameter and put a int return value:

public int Do(int arg1, int arg2)

There are some good things about out parameters:

  1. Output parameters are initially considered unassigned.
  • Every out parameter must be definitely assigned before the method returns, your code will not compile if you miss an assignment.

In conclusion, I basically try use out params in my private API to avoid creating separate types to wrap multiple return values, and on my public API, I only use them on methods that match with the TryParse pattern.

Solution 6 - C#

Yes, it does make sense. Take this for example.

String strNum = "-1";
Int32 outNum;

if (Int32.TryParse(strNum, out outNum)) {
    // success
}
else {
    // fail
}

What could you return if the operation failed in a normal function with a return value? You most certainly could not return -1 to represent a fail, because then there would be no differentiation between the fail-return value and the actual value that was being parsed to begin with. This is why we return a Boolean value to see if it succeeded, and if it did then we have our "return" value safely assigned already.

Solution 7 - C#

Creating a type just for returning values sounds little painful to me :-) First i will have to create a type for returning the value then in the calling method i have assign the value from the returned type to the actual variable that needs it.

Out parameters are simipler to use.

Solution 8 - C#

It does annoy me that I can't pass in null to the out parameter for the TryParse functions.

Still, I prefer it in some cases to returning a new type with two pieces of data. Especially when they're unrelated for the most part or one piece is only needed for a single operation a moment after. When I do need to save the resulting value of a TryParse function I really like having an out parameter rather than some random ResultAndValue class that I have to deal with.

Solution 9 - C#

If you always create a type, then you can end up with a lot of clutter in your application.

As said here, one typical use case is a TrySomething Method where you want to return a bool as an indicator for success and then the actual value. I also find that a little bit cleaner in an if-statement - all three options roughly have the same LOC anyway.

int myoutvalue;
if(int.TryParse("213",out myoutvalue){
    DoSomethingWith(myoutvalue);
}

vs.

ParseResult<int> myoutvalue = int.TryParse("213");
if ( myoutvalue.Success ) {
    DoSomethingWith(myoutvalue.Value);
}

vs.

int? myoutvalue = int.TryParse("213");
if(myoutvalue.HasValue){
    DoSomethingWith(myoutvalue.Value);
}

As for the "Why not return a Nullable Type": TryParse exists since Framework 1.x, whereas Nullable Types came with 2.0 (As they require Generics). So why unneccessarily break compatibility or start introducing inconsistencies between TryParse on some types? You can always write your own extension Method to duplicate functionality already existing (See Eric Lipperts Post on an unrelated subject that includes some reasoning behind doing/not doing stuff)

Another use case is if you have to return multiple unrelated values, even though if you do that that should trigger an alarm that your method is possibly doing too much. On the other hand, if your Method is something like an expensive database or web service call and you want to cache the result, it may make sense to do that. Sure, you could create a type, but again, that means one more type in your application.

Solution 10 - C#

I use out parameters sometimes for readability, when reading the method name is more important than whatever the output of the method is—particularly for methods that execute commands in addition to returning results.

StatusInfo a, b, c;

Initialize(out a);
Validate(a, out b);
Process(b, out c);

vs.

StatusInfo a = Initialize();
StatusInfo b = Validate(a);
StatusInfo c = Process(b);

At least for me, I put a lot of emphasis on the first few characters of each line when I'm scanning. I can easily tell what's going on in the first example after acknowledging that some "StatusInfo" variables are declared. In the second example, the first thing I see is that a bunch of StatusInfo is retrieved. I have to scan a second time to see what kind of effects the methods may have.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionkay.oneView Question on Stackoverflow
Solution 1 - C#jasonhView Answer on Stackoverflow
Solution 2 - C#GishuView Answer on Stackoverflow
Solution 3 - C#devuxerView Answer on Stackoverflow
Solution 4 - C#ThomasVestergaardView Answer on Stackoverflow
Solution 5 - C#Christian C. SalvadóView Answer on Stackoverflow
Solution 6 - C#David AndersonView Answer on Stackoverflow
Solution 7 - C#chikakView Answer on Stackoverflow
Solution 8 - C#Spencer RuportView Answer on Stackoverflow
Solution 9 - C#Michael StumView Answer on Stackoverflow
Solution 10 - C#Mark CidadeView Answer on Stackoverflow