169

If we want to get a value from a method, we can use either return value, like this:

public int GetValue(); 

or:

public void GetValue(out int x);

I don't really understand the differences between them, and so, don't know which is better. Can you explain me this?

Thank you.

Delta76
  • 13,931
  • 30
  • 95
  • 128
  • 3
    I wish C# had multiple return values like Python, for example. – Trap Aug 21 '15 at 22:48
  • 16
    @Trap You can return a `Tuple` if you want, but the general consensus is that if you need to return more than one thing, the things are usually related somehow and that relation is usually best expressed as a class. – Pharap Jun 22 '16 at 20:23
  • 2
    @Pharap Tuples in C# in its current form are just ugly, but that's just my opinion. On the other hand, "general consensus" means nothing from an usability and productivity point of view. You wouldn't create a class for returning a couple of values for the same reason you wouldn't create a class to return a couple of values as a ref/out parameter. – Trap Jun 22 '16 at 23:55
  • @Trap `return Tuple.Create(x, y, z);` Isn't that ugly. Besides, it's a late in the day to have them introduced at language level. The reason I wouldn't create a class to return values from a ref/out parameter is because ref/out params only really make sense for large mutable structs (like matrices) or optional values, and the latter is debatable. – Pharap Jun 23 '16 at 01:02
  • @Pharap C# team is actively looking to introduce tuples at language level. While it is welcome the whole plethora of options in .NET overwhelming now - anonymous type, .NET `Tuple<>` and C# tuples!. I just wished C# allowed returning of anonymous types from methods with compiler inferring type (like `auto` in Dlang). – nawfal Jun 24 '16 at 15:25
  • @nawfal I think I'd prefer tuples to anonymous types. The flaw with that is it would mean the method signature would have to include a way of identifying the anonymous type. It could just return `object` but that would be pretty useless, and if the method was made public, anyone attempting to use it would have to know what fields the object contained (which would be awkward when they don't have access to the method's source code). – Pharap Jun 25 '16 at 16:03
  • @Pharap if C# team wanted they could *infer* the type. Similar to type inference in case of `var x = new { };` That's what Dlang's `auto` does. So method definition can look like `public var Method() { }`. You anyway need language level support be it tuples or anonymous types. – nawfal Jun 25 '16 at 18:31
  • @nawfal That's not the problem, the problem is exporting the function or using it when you don't have access to the source code for the function body. How does one identify the members of a `var` type? Presumably one would have to examine some form of compiler produced metadata, which is not always practical. – Pharap Jun 26 '16 at 03:45
  • @Pharap what problem do you see in exporting an anonymous type that exporting a named type doesn't have (or for that matter even tuples)? Anonymous types are just normal types but without a name (the compiler gives it the name instead of programmer). True language currently doesnt support cross assembly anonymous types but it's a matter of supporting. I dont see a technical or theoretical challenge. – nawfal Jun 26 '16 at 06:36

18 Answers18

166

Return values are almost always the right choice when the method doesn't have anything else to return. (In fact, I can't think of any cases where I'd ever want a void method with an out parameter, if I had the choice. C# 7's Deconstruct methods for language-supported deconstruction acts as a very, very rare exception to this rule.)

Aside from anything else, it stops the caller from having to declare the variable separately:

int foo;
GetValue(out foo);

vs

int foo = GetValue();

Out values also prevent method chaining like this:

Console.WriteLine(GetValue().ToString("g"));

(Indeed, that's one of the problems with property setters as well, and it's why the builder pattern uses methods which return the builder, e.g. myStringBuilder.Append(xxx).Append(yyy).)

Additionally, out parameters are slightly harder to use with reflection and usually make testing harder too. (More effort is usually put into making it easy to mock return values than out parameters). Basically there's nothing I can think of that they make easier...

Return values FTW.

EDIT: In terms of what's going on...

Basically when you pass in an argument for an "out" parameter, you have to pass in a variable. (Array elements are classified as variables too.) The method you call doesn't have a "new" variable on its stack for the parameter - it uses your variable for storage. Any changes in the variable are immediately visible. Here's an example showing the difference:

using System;

class Test
{
    static int value;

    static void ShowValue(string description)
    {
        Console.WriteLine(description + value);
    }

    static void Main()
    {
        Console.WriteLine("Return value test...");
        value = 5;
        value = ReturnValue();
        ShowValue("Value after ReturnValue(): ");

        value = 5;
        Console.WriteLine("Out parameter test...");
        OutParameter(out value);
        ShowValue("Value after OutParameter(): ");
    }

    static int ReturnValue()
    {
        ShowValue("ReturnValue (pre): ");
        int tmp = 10;
        ShowValue("ReturnValue (post): ");
        return tmp;
    }

    static void OutParameter(out int tmp)
    {
        ShowValue("OutParameter (pre): ");
        tmp = 10;
        ShowValue("OutParameter (post): ");
    }
}

Results:

Return value test...
ReturnValue (pre): 5
ReturnValue (post): 5
Value after ReturnValue(): 10
Out parameter test...
OutParameter (pre): 5
OutParameter (post): 10
Value after OutParameter(): 10

The difference is at the "post" step - i.e. after the local variable or parameter has been changed. In the ReturnValue test, this makes no difference to the static value variable. In the OutParameter test, the value variable is changed by the line tmp = 10;

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 2
    You made me believe that return value is much better :). But I still wonder what happens "in depth". I mean, the return value, and the out parameter, are they different in the way they are created, assigned and returned? – Delta76 May 01 '09 at 09:49
  • 2
    TryParse is the best example of when using an out param is appropriate & clean. Although I have used it in special cases like if (WorkSucceeded(out List errors) which is basically the same pattern as TryParse – Chad Grant May 01 '09 at 10:05
  • TryParse for value types can also be represented using nullable value types. Sometimes that's cleaner, sometimes not. – Jon Skeet May 01 '09 at 10:08
  • You might want to use Out parameters if you have two methods with the same name and no other input parameters. You can then have a kind of odd polymorphic overloading. I think it's pretty contrived as you'd almost definitely want to rename you methods. – AndyM Jun 27 '11 at 02:02
  • You might need to use an `out` variable in places like XNA, where stack performance could be a bottleneck. Returning is more expensive for larger structs. – user541686 Feb 27 '12 at 23:09
  • 3
    A poor an unhelpful answer. As explained in the comments on [this question](http://stackoverflow.com/questions/11212759/c-sharp-out-parameters-vs-returns), out parameters have several useful advantages. Preference between out vs return should depend on the situation. – aaronsnoswell Dec 17 '12 at 20:55
  • 2
    @aaronsnoswell: Which precise comments? Bear in mind that the example of `Dictionary.TryGetValue` is *not* applicable here, as that's not a void method. Can you explain why you'd want an `out` parameter **instead** of a return value? (Even for `TryGetValue`, I'd prefer a return value which contains all the output information, personally. See NodaTime's `ParseResult` for an example of how I'd have designed it.) – Jon Skeet Dec 18 '12 at 09:12
  • if it has to return multiple values which one would be better ? – Sankara Jan 06 '13 at 22:05
  • @1010101: It depends on the context. Are those values related? Are you going to use that relationship in multiple places? – Jon Skeet Jan 07 '13 at 06:49
  • for both the scenarios? related and non related values – Sankara Jan 07 '13 at 12:10
  • @1010101: You'd need to give concrete examples - ideally as a new question. It's not really a good use of SO comments. – Jon Skeet Jan 07 '13 at 12:36
  • I wholeheartedly disagree with this answer. This article essentially says “avoid using out parameters unless you know what you are doing,” but the feature exists for a reason. My use case is you have a UI layer that sends data to a Business Layer, but needs to know if the operation succeeded. By forcing the user to pass in the out variable you indicate that they actually need to be aware of it. E.g. public bool AddItem(item) is less meaningful than public void AddItem(item, out success). – personaelit Feb 21 '14 at 18:41
  • 1
    @Jim: Lots of features exist for a reason but shouldn't be used lightly... and I would definitely take issue with your example. In particular, success of an operation should very rarely be indicated with a `bool` value anyway - if the reason the business layer didn't add the item is due to some constraint violation, I'd expect an exception to be thrown rather than a true/false response. (I view this as pretty different to TryParse or ISet.Add type scenarios.) – Jon Skeet Feb 21 '14 at 18:44
  • @JonSkeet There could be other architectural problems with the layering in my use case, but if I wanted to handle the exception, but also display a notification in the UI, I think this would be the right way to do it. Also, this was the article I was referencing. http://msdn.microsoft.com/en-us/library/ms182131.aspx – personaelit Feb 21 '14 at 18:56
  • @Jim: Yes, that's the article - but you seem to assume that "feature exists for a reason" goes against "avoid using it unless you know what you're doing". And I don't see why handling an exception and displaying a notification would mean using an `out` parameter - I'd just catch the exception in the UI layer... I've never said that you should *never* use `out` parameters... I'd just avoid them *almost* always. – Jon Skeet Feb 21 '14 at 19:07
  • @JonSkeet Point taken. The use of "better" in the question lends to it being subjective. I'll agree with you, but if happy-UI-developer never considers that he needs to catch an exception and thinks he can just AddItem and be on his merry way then poor code may be written. Whereas I think an out parameter is like a poor man's contract, or at least a caution flag. – personaelit Feb 21 '14 at 19:22
  • 2
    @Jim: I guess we'll have to agree to disagree. While I see your point about hammering people over the head with this, it also makes it less friendly for those who *do* know what they're doing. The nice thing about an exception rather than a return value is that you can't easily *ignore* it and carry on as if nothing happened... whereas with both a return value and an `out` parameter, you can just not do anything with the value. – Jon Skeet Feb 21 '14 at 20:45
  • As one who dislikes exceptons—and I am [not alone](http://www.joelonsoftware.com/items/2003/10/13.html) in this sentiment—I will often `return` an error code or flag and provide the actual result via an `out` parameter. – Anton Shepelev Nov 10 '16 at 15:51
  • out parameters are best used in scenarios where you have a method with a name and can return multiple type of values, instead of creating a different name for every variant, you can just have a variant of it with the same name, as the signature will be different. Such cases include, where you want a method to load data from file and output it to different object types. You can have a string, vector, int, int[] all without having different names as they already require a different signature, yes, other methods still apply to have a solution for this, but this is one of them. – Clayton C Apr 12 '17 at 12:26
  • 1
    @ClaytonC: And of course with C# 7, tuples provide an alternative (and better, I'd argue) approach. – Jon Skeet Apr 12 '17 at 12:35
  • @JonSkeet, one quick question, I stumbled upon this same issue today. `out parameter in a recursion has only 1 variable being used, vs return values are many` - is this true? Please assume recursion can be a depth of 100+ or as big as it can be, with few other parameters already given to the function. Also please assume the variable as `long long` out parameter vs returning `long long` value. Is this the case (recursion with a lot of depth & return value type is big) when amost always it should be out parameter, instead of return value? – Manohar Reddy Poreddy Apr 06 '19 at 13:14
  • @ManoharReddyPoreddy: `long long` isn't even a type in C#, so I'm not quite sure what you mean. But even when the storage itself is being shared, that doesn't mean nothing needs to be put on the stack for an `out` parameter. You still need a pointer to that storage location, effectively. I would only change to use an `out` parameter for efficiency (or to facilitate a deeper stack) after *proving* that it's useful. – Jon Skeet Apr 06 '19 at 13:24
  • @JonSkeet oh, I was referring to C++, long long is longer than long, and generally we share out parameter it as a reference to not allocate memory (for example, https://stackoverflow.com/questions/10446907/why-reference-size-is-always-4-bytes-c#comment13487829_10446973). Though I would agree now for my case (my competitive programming problem I solved) return val works & looks better, but when memory constrained, out param can benefit from less memory used (as reference is an alias, not a new variable or pointer in general), with less readability, surely for Dynamic Programming problems case. – Manohar Reddy Poreddy Apr 06 '19 at 15:20
  • @ManoharReddyPoreddy: You still need to *pass the pointer* to that storage location to the method. That's going to be the same size as a `long` in 64 bit CLRs. – Jon Skeet Apr 06 '19 at 16:51
  • @JonSkeet: May be not always? https://stackoverflow.com/a/6462474/984471, Also would that mean, you agree on out param being better than return value? For example, for a `long long` variable for efficiency, maybe on 32 bit, sometimes on 64 bit? – Manohar Reddy Poreddy Apr 07 '19 at 01:51
  • @ManoharReddyPoreddy: I'm not going to speculate on what's suitable in a *different language*. If you want to talk about C#, please talk about C# types. But a `long` in C# is always 64 bits, and a reference in a 64-bit CLR is always 64 bits too. – Jon Skeet Apr 07 '19 at 07:24
30

What's better, depends on your particular situation. One of the reasons out exists is to facilitate returning multiple values from one method call:

public int ReturnMultiple(int input, out int output1, out int output2)
{
    output1 = input + 1;
    output2 = input + 2;

    return input;
}

So one is not by definition better than the other. But usually you'd want to use a simple return, unless you have the above situation for example.

EDIT: This is a sample demonstrating one of the reasons that the keyword exists. The above is in no way to be considered a best practise.

pyrocumulus
  • 9,072
  • 2
  • 43
  • 53
  • 2
    I disagree with this, why wouldn't you return a data structure with 4 ints? This is really confusing. – Chad Grant May 01 '09 at 09:45
  • 1
    Obviously there are more (and better) ways to return multiple values, I'm just giving the OP a reason why out exists in the first place. – pyrocumulus May 01 '09 at 09:47
  • 3
    I agree with @Cloud. Just because it isn't the best way doesn't mean it should not exist. – Cerebrus May 01 '09 at 09:52
  • Well the code won't even compile for one ... and it should at least mention that it's considered bad practice / not preferred. – Chad Grant May 01 '09 at 09:58
  • 3
    It won't compile? And why is that? This sample could compiles just perfect. And please, I'm giving a sample of why a particular syntax/keyword exists, not a lesson in best practices. – pyrocumulus May 01 '09 at 10:23
25

You should generally prefer a return value over an out param. Out params are a necessary evil if you find yourself writing code that needs to do 2 things. A good example of this is the Try pattern (such as Int32.TryParse).

Let's consider what the caller of your two methods would have to do. For the first example I can write this...

int foo = GetValue();

Notice that I can declare a variable and assign it via your method in one line. FOr the 2nd example it looks like this...

int foo;
GetValue(out foo);

I'm now forced to declare my variable up front and write my code over two lines.

update

A good place to look when asking these types of question is the .NET Framework Design Guidelines. If you have the book version then you can see the annotations by Anders Hejlsberg and others on this subject (page 184-185) but the online version is here...

http://msdn.microsoft.com/en-us/library/ms182131(VS.80).aspx

If you find yourself needing to return two things from an API then wrapping them up in a struct/class would be better than an out param.

isherwood
  • 58,414
  • 16
  • 114
  • 157
Martin Peck
  • 11,440
  • 2
  • 42
  • 69
  • Great answer, especially the reference to TryParse, a (common) function which forces developers to use the (uncommon) out variables. – Cerebrus May 01 '09 at 09:50
16

There's one reason to use an out param which has not already been mentioned: the calling method is obliged to receive it. If your method produces a value which the caller should not discard, making it an out forces the caller to specifically accept it:

 Method1();  // Return values can be discard quite easily, even accidentally

 int  resultCode;
 Method2(out resultCode);  // Out params are a little harder to ignore

Of course the caller can still ignore the value in an out param, but you've called their attention to it.

This is a rare need; more often, you should use an exception for a genuine problem or return an object with state information for an "FYI", but there could be circumstances where this is important.

8

It's preference mainly

I prefer returns and if you have multiple returns you can wrap them in a Result DTO

public class Result{
  public Person Person {get;set;}
  public int Sum {get;set;}
}
Scott Cowan
  • 2,652
  • 7
  • 29
  • 45
6

You should almost always use a return value. 'out' parameters create a bit of friction to a lot of APIs, compositionality, etc.

The most noteworthy exception that springs to mind is when you want to return multiple values (.Net Framework doesn't have tuples until 4.0), such as with the TryParse pattern.

shA.t
  • 16,580
  • 5
  • 54
  • 111
Brian
  • 117,631
  • 17
  • 236
  • 300
  • Not sure if its a good practice but Arraylist can also be used to return multiple values. – B A Dec 19 '17 at 11:34
  • @BA no it's not a good practice, other users wouldn't know what this Arraylist contains, or at what position they are at. For example I want to return the amount of bytes read and also the value. out or tuples which are named would be much better. ArrayList, or any other list would be only useful if you want to return a collaction of things, for example a list of persons. – slow Sep 10 '18 at 08:05
5

You can only have one return value whereas you can have multiple out parameters.

You only need to consider out parameters in those cases.

However, if you need to return more than one parameter from your method, you probably want to look at what you're returning from an OO approach and consider if you're better off return an object or a struct with these parameters. Therefore you're back to a return value again.

Robin Day
  • 100,552
  • 23
  • 116
  • 167
3

Additionally, return values are compatible with asynchronous design paradigms.

You cannot designate a function "async" if it uses ref or out parameters.

In summary, Return Values allow method chaining, cleaner syntax (by eliminating the necessity for the caller to declare additional variables), and allow for asynchronous designs without the need for substantial modification in the future.

firetiger77
  • 351
  • 3
  • 9
  • Great point on the "async" designation. Thought someone else would've mentioned that. Chaining - as well as using the return value (indeed the function itself) as an expression is another key bene. It's really the difference between considering only how to just get stuff back from a process (the "bucket" - Tuple/class/struct discussion) and treating the process itself like an expression that can be substituted for a single value (the usefulness of the function itself, because it returns only 1 value). – galaxis Oct 24 '17 at 21:00
3

I would prefer the following instead of either of those in this simple example.

public int Value
{
    get;
    private set;
}

But, they are all very much the same. Usually, one would only use 'out' if they need to pass multiple values back from the method. If you want to send a value in and out of the method, one would choose 'ref'. My method is best, if you are only returning a value, but if you want to pass a parameter and get a value back one would likely choose your first choice.

kenny
  • 21,522
  • 8
  • 49
  • 87
3

I think one of the few scenarios where it would be useful would be when working with unmanaged memory, and you want to make it obvious that the "returned" value should be disposed of manually, rather than expecting it to be disposed of on its own.

xian
  • 4,657
  • 5
  • 34
  • 38
2

Using the out keyword with a return type of bool, can sometimes reduce code bloat and increase readability. (Primarily when the extra info in the out param is often ignored.) For instance:

var result = DoThing();
if (result.Success)
{
    result = DoOtherThing()
    if (result.Success)
    {
        result = DoFinalThing()
        if (result.Success)
        {
            success = true;
        }
    }
}

vs:

var result;
if (DoThing(out result))
{
    if (DoOtherThing(out result))
    {
        if (DoFinalThing(out result))
        {
            success = true;
        }
    }
}
Paul Smith
  • 166
  • 3
  • 13
2

Please avoid using out parameters.

Although, they can make sense in certain situations (for example when implementing the Try-Parse Pattern), they are very hard to grasp.

Chances to introduce bugs or side effects by yourself (unless you are very experienced with the concept) and by other developers (who either use your API or may inherit your code) is very high.

According to Microsoft's quality rule CA1021:

Although return values are commonplace and heavily used, the correct application of out and ref parameters requires intermediate design and coding skills. Library architects who design for a general audience should not expect users to master working with out or ref parameters.

Therefore, if there is not a very good reason, please just don't use out or ref.

See also:

Thomas
  • 8,357
  • 15
  • 45
  • 81
2

There is no real difference. Out parameters are in C# to allow method return more then one value, that's all.

However There are some slight differences , but non of them are really important:

Using out parameter will enforce you to use two lines like:

int n;
GetValue(n);

while using return value will let you do it in one line:

int n = GetValue();

Another difference (correct only for value types and only if C# doesn't inline the function) is that using return value will necessarily make a copy of the value when the function return, while using OUT parameter will not necessarily do so.

isherwood
  • 58,414
  • 16
  • 114
  • 157
user88637
  • 11,790
  • 9
  • 37
  • 36
2

As others have said: return value, not out param.

May I recommend to you the book "Framework Design Guidelines" (2nd ed)? Pages 184-185 cover the reasons for avoiding out params. The whole book will steer you in the right direction on all sorts of .NET coding issues.

Allied with Framework Design Guidelines is the use of the static analysis tool, FxCop. You'll find this on Microsoft's sites as a free download. Run this on your compiled code and see what it says. If it complains about hundreds and hundreds of things... don't panic! Look calmly and carefully at what it says about each and every case. Don't rush to fix things ASAP. Learn from what it is telling you. You will be put on the road to mastery.

Bellarmine Head
  • 3,397
  • 2
  • 22
  • 31
1

Both of them have a different purpose and are not treated the same by the compiler. If your method needs to return a value, then you must use return. Out is used where your method needs to return multiple values.

If you use return, then the data is first written to the methods stack and then in the calling method's. While in case of out, it is directly written to the calling methods stack. Not sure if there are any more differences.

danish
  • 5,550
  • 2
  • 25
  • 28
  • The methods stack? I'm no c# expert, but x86 only supports one stack per thread. The method's "frame" is deallocated during return, and if a context switch happend then the deallocated stack can be overwritten. In c all return values goes in registry eax. If you like to return objects/structs they need to be allocated to the heap and the pointer will be put in eax. – Stefan Lundström May 01 '09 at 10:02
0

out is more useful when you are trying to return an object that you declare in the method.

Example

public BookList Find(string key)
{
   BookList book; //BookList is a model class
   _books.TryGetValue(key, out book) //_books is a concurrent dictionary
                                     //TryGetValue gets an item with matching key and returns it into book.
   return book;
}
0

return value is the normal value which is returned by your method.

Where as out parameter, well out and ref are 2 key words of C# they allow to pass variables as reference.

The big difference between ref and out is, ref should be initialised before and out don't

bizimunda
  • 819
  • 2
  • 9
  • 26
-3

I suspect I'm not going to get a look-in on this question, but I am a very experienced programmer, and I hope some of the more open-minded readers will pay attention.

I believe that it suits object-oriented programming languages better for their value-returning procedures (VRPs) to be deterministic and pure.

'VRP' is the modern academic name for a function that is called as part of an expression, and has a return value that notionally replaces the call during evaluation of the expression. E.g. in a statement such as x = 1 + f(y) the function f is serving as a VRP.

'Deterministic' means that the result of the function depends only on the values of its parameters. If you call it again with the same parameter values, you are certain to get the same result.

'Pure' means no side-effects: calling the function does nothing except computing the result. This can be interpreted to mean no important side-effects, in practice, so if the VRP outputs a debugging message every time it is called, for example, that can probably be ignored.

Thus, if, in C#, your function is not deterministic and pure, I say you should make it a void function (in other words, not a VRP), and any value it needs to return should be returned in either an out or a ref parameter.

For example, if you have a function to delete some rows from a database table, and you want it to return the number of rows it deleted, you should declare it something like this:

public void DeleteBasketItems(BasketItemCategory category, out int count);

If you sometimes want to call this function but not get the count, you could always declare an overloading.

You might want to know why this style suits object-oriented programming better. Broadly, it fits into a style of programming that could be (a little imprecisely) termed 'procedural programming', and it is a procedural programming style that fits object-oriented programming better.

Why? The classical model of objects is that they have properties (aka attributes), and you interrogate and manipulate the object (mainly) through reading and updating those properties. A procedural programming style tends to make it easier to do this, because you can execute arbitrary code in between operations that get and set properties.

The downside of procedural programming is that, because you can execute arbitrary code all over the place, you can get some very obtuse and bug-vulnerable interactions via global variables and side-effects.

So, quite simply, it is good practice to signal to someone reading your code that a function could have side-effects by making it non-value returning.

debater
  • 466
  • 6
  • 11
  • > If you sometimes want to call this function but not get the count, you could always declare an overloading. In C# version 7 (I think) and later, you can use the `_` discard symbol to ignore an out parameter, e.g.: DeleteBasketItems(category, out _); – debater Jun 30 '20 at 21:27