views:

798

answers:

11

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.

A: 

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
A: 

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
+6  A: 

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.

Cloud
I disagree with this, why wouldn't you return a data structure with 4 ints? This is really confusing.
Chad Grant
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.
Cloud
I agree with @Cloud. Just because it isn't the best way doesn't mean it should not exist.
Cerebrus
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
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.
Cloud
You're right, my bad. I misread it, will delete my comment.
Chad Grant
I click delete and it says "Really delete this comment?" I click yes and it says "You cannot vote for this comment" :(
Chad Grant
I've been having the same problem all day. No problem :)
Cloud
+2  A: 

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.

Brian
+22  A: 

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.)

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
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?
Vimvq1987
Yes. I'll edit to show an example of a difference.
Jon Skeet
Chad Grant
TryParse for value types can also be represented using nullable value types. Sometimes that's cleaner, sometimes not.
Jon Skeet
@Jon: great answer, as usual. Thank you.
Vimvq1987
+10  A: 

You should generally prefer a return value over an out param. Out params are a neccissary 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.

Martin Peck
Great answer, especially the reference to TryParse, a (common) function which forces developers to use the (uncommon) out variables.
Cerebrus
A: 

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
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
+1  A: 

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
A: 

There is no real difference , out parameters are in C# to allow method return more then one value , thats all.

However There are some slight differences , but non of them are realy 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.

+1  A: 

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.

Andrew Webb
A: 

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.

kitchen