1

Are there any substantial side effects or downfalls to using the out parameter in C#? And would I be able to return two or more objects back?

I am new to C# and I have never returned values for a method through it's parameters. I thought it was quite useful when you need to return more than 1 object, but I want to make sure there are no major downfalls to doing this.

    static int doubleScore(out int i, int score)
    {
        return score*2;
    }
    static void Main()
    {
        int score = 10;
        int newScore = 0;

        doubleScore(out newScore, score);
        // newScore = 20
    }

compared to:

    static int doubleScore(int score)
    {
        return score*2;
    }
    static void Main()
    {
        int newScore = 0;
        int score = 10;
        newScore = doubleScore(score);
        // newScore is now 20
    }
Jaiesh_bhai
  • 1,778
  • 8
  • 26
  • 41
  • possible duplicate of [C# out parameters vs returns](http://stackoverflow.com/questions/11212759/c-sharp-out-parameters-vs-returns) – Mark Pattison Oct 04 '13 at 20:42
  • 4
    a `void` method with an `out` parameter doesn't make sense, IMO. Just have the method return `int` and avoid the `out` stuff. – Federico Berasategui Oct 04 '13 at 20:45
  • 1
    Just a note: Your int doubleScore() method needs to return score * 2, not assign it to i. – Michael Oct 04 '13 at 20:50
  • Microsofts Code Analysis indicates you should [Avoid out parameters](http://msdn.microsoft.com/en-us/library/ms182131.aspx/html). It gives no good reasons for this other than that it is non-standard and may confuse less experienced programmers. Though that may be reason enough... – Daniel Oct 04 '13 at 20:50
  • @MarkPattison I have edited the question. I wanted to know if you can use it for more than one return. – Jaiesh_bhai Oct 04 '13 at 21:02

7 Answers7

3

Pain points of out:

  • you can't chain methods easily
  • you can't use such methods in LINQ queries easily (i.e. try use int.TryParse when converting list of string to list of integers with LINQ Select) and in functional code in general
  • out arguments get quite complicated in asynchronous code
  • using var for variables passed as out parameters will often lead to "value assigned but never used" warning ( var resultOfTryParse = 1; int.TryParse("2", out resultOfTryParse) )
  • you have to always assign value in the function even if there is no good value to assign (usually end up with outParam = 0/null at the beginning of the method)

Whenever you feel out is required try to return custom class that incorporates all return values - may be more usable.

Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179
2

Using the out keyword is generally a practice of last resort.

It makes the code a little harder to read, and less flexible. For example, let's say you want to do this:

int score = 10;
int doubledScore = doubleScore(score);
int quadroupledScore = doubleScore(doubledScore);

Now if you were using out parameters...

int score = 10;
int doubledScore;
doubleScore(out doubledScore, score);
int quadroupledScore;
doubleScore(out quadroupledScore, doubledScore);

That's quite a bit more confusing. Now let's say you had a method you wanted to call with nested functions as parameters:

int score = 10;
var message = String.Format("Your number is {0}.  When doubled it is {1}.", score, doubleScore(score));

Using out parameters that becomes:

int score = 10;
int doubledScore;
doubleScore(out doubledScore, score);
var message = String.Format("Your number is {0}.  When doubled it is {1}.", score, doubledScore);

Less flexible and more verbose.

Trevor Elliott
  • 11,292
  • 11
  • 63
  • 102
1

Well, in this specific case, using an out parameter isn't very useful (since you're only returning one value), and it makes the code less readable.

but I want to make sure there are no major downfalls to doing this

No, there aren't any obvious downfalls or side effects, but there are a few limitations to where you can use out parameters. For instance, you can't use them in iterators or async methods.

Thomas Levesque
  • 286,951
  • 70
  • 623
  • 758
  • Also... Out parameters and multithreading in general can lead to ugly mess. – Tetsujin no Oni Oct 04 '13 at 20:47
  • @TetsujinnoOni That depends on whether the reference variables are accessed from multiple threads. If they are, then yes, if not, it's not really any different. – Servy Oct 04 '13 at 20:49
  • Right, but my point was that awareness that unguarded writes to the `out` parameters from multiple threads will cause problems is definitely something to be aware of when doing multithreading... (and if that parameter is a collection that is iterated in multiple threads... rethinking your access mechanism to the collection might be in order, eh?) – Tetsujin no Oni Oct 04 '13 at 20:56
1

Assuming you fixed the mistakes in your example, there would be no reason to use the "parameter version" of your function. Out is of limited utility, as it should only be used to return "extra values" from a function call. The method quickly becomes clunky if you try to return lots of values. It is not really a compiler issue, or code generation problem, it is just painful to use.

I would always declare a method result class to return 3 values or more, e.g.

public class DoubleScoreResult
{
  double value {get; private set}
  bool success {get; private set}
  Exception ex {get; private set};
}

function DoubleScoreResult DoubleScore()
{
  var result = new DoubleScoreResult();

   ...

  return result;
}
Servy
  • 202,030
  • 26
  • 332
  • 449
Gary Walker
  • 8,831
  • 3
  • 19
  • 41
1

One of the major downsides is out parameters make the code less readable and less expressive. Parameters are made for accepting values into a method, return values are what comes out. I personally would rather keep them clearly separated.

If you want to return multiple values or objects then the better - or maybe cleaner - way would be to wrap them in another object. Perhaps a tuple or something more explicit.

Dennis Traub
  • 50,557
  • 7
  • 93
  • 108
0

An example to point out when the out parameter is useful:

The out parameter is useful, when you wants to try to parse a string to an integer.

The returning type will be boolean telling whether the parse was successfull or not. The out parameter will set the references variable to the parsed integer. As you can see, it is used in bool int.TryParse(string s, out int i).

  • 2
    It was useful when these methods were first designed, but with the addition of nullable types in C# 2, returning a Nullable would have been a better approach – Thomas Levesque Oct 04 '13 at 20:49
  • Or, for that matter, one could simply return a `Tuple` or some other composite object (which is essentially what Nullable is, but with some added syntactic sugar). Logically the only reason `TryParse` uses `out` is because it needs to return two things, not because trying to do something is special in any way. – Servy Oct 04 '13 at 20:50
  • Yes, in my opinion, the out parameter is obsolete. I never really was forced to use it. – Dennis Ziolkowski Oct 04 '13 at 20:51
0

The main disadvantage is that when using out you are forced to have an explicit named storage location (i.e. a local variable) to store the result. When you are returning a value you can compose function calls without ever storing the result in a named variable. To give an example:

Console.WriteLine(doubleScore(2));

vs.

int result;
doubleScore(out result, 2);
Console.WriteLine(result);

It makes the code a lot more verbose, and it requires using statements that cause side effects whenever using the code. These factors make the method much, much harder to use in, for example, a LINQ query.

Servy
  • 202,030
  • 26
  • 332
  • 449