Which Is Better, Return Value or Out Parameter

Which is better, return value or out parameter?

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;

C# out parameters vs returns

A good use of out instead of return for the result is the Try pattern that you can see in certain APIs, for example Int32.TryParse(...). In this pattern, the return value is used to signal success or failure of the operation (as opposed to an exception), and the out parameter is used to return the actual result.

One of the advantages with respect to Int32.Parse is speed, since exceptions are avoided. Some benchmarks have been presented in this other question: Parsing Performance (If, TryParse, Try-Catch)

Performance consideration when using an out parameter and return value?

The out keyword causes arguments to be passed by reference. This is like the ref keyword, except that ref requires that the variable be initialized before it is passed. To use an out parameter, both the method definition and the calling method must explicitly use the out keyword. For example:

class OutExample
{
static void Method(out int i)
{
i = 44;
}
static void Main()
{
int value;
Method(out value);
// value is now 44
}
}

Reference of out

Reference 2

Return
The return statement terminates execution of the method in which it appears and returns control to the calling method. It can also return an optional value. If the method is a void type, the return statement can be omitted.

If the return statement is inside a try block, the finally block, if one exists, will be executed before control returns to the calling method.

class ReturnTest
{
static double CalculateArea(int r)
{
double area = r * r * Math.PI;
return area;
}

static void Main()
{
int radius = 5;
double result = CalculateArea(radius);
Console.WriteLine("The area is {0:0.00}", result);

// Keep the console open in debug mode.
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
// Output: The area is 78.54

Return Reference

Difference between using out parameter and return in C#

Well don’t know how if you know C++ but it is quite similar to C++ where you can pass a parameter to function as a reference. So, function is indeed returning just one string, but it will also set the value of wasWhisperCalled. So if wasWhisperCalled was false before function call, then after the function call it will be set to true. Hope this clarifies this a little bit more.

Efficiency of output parameter vs return value on the stack for stl data structures

Taking the value as a reference parameter has the following properties:

  1. No copying, moving, or any other operation will be done.
  2. The return value cannot be immediately discarded on the user's side. They can't just shove a temporary at your function's reference parameter or something. They must declare a variable, and therefore they must give it a name which will live within the current scope.
  3. The API suggests that the value is an input/output parameter. That is, there is a value being passed in which will be read and written. If that is not the case, then using it represents a sub-optimal API design element.

Returning the value has the following properties:

  1. If copy elision is not available (either due to the nature of the function's implementation, a poor compiler, or that the return value is not initializing a new value), then the return value will be moved. Not copied. Movement is not free, but generally it is not much more expensive than a few pointer copies. No new objects or memory will be allocated or deallocated.
  2. The API enforces the output nature of the value. There is no way for the user to play with the output it passes in because it doesn't pass anything in. Similarly, there is no way for the function to read any values because it doesn't take anything in. It is an output value, period; the function generates it and returns it.
  3. The return value can be discarded immediately at the user's discretion. Obviously if users are doing this a lot, it suggests that something is wrong, but it is up to the user to decide if they want to keep the output value or not. The C++17 [[nodiscard]] attribute can be used in cases where discarding the value is categorically incorrect.

In C++ Output Parameter vs Return Value


  • The return value is something well defined in C++; for instance, x in return x; is the return value, whereas int in the function declaration int myfunc() is the return type.
  • The concpet of output paramters is not defined in C++. However someone would interpret it as either of the following:

    • function parameters passed by non-const reference, as long as you actually modify it in the function, otherwise why would you call it output? An example is x in the following function declaration: void myfunc(int& x);
    • function parameters passed by (not necessarily const) pointer to non-const, like x in both the following function declarations: void fun1(int * x) and void fun2(int * const x);

      • concerning this latter case, it allows "encoding" a missing parameter in as a nullptr default value, as in void fun3(int * x = nullptr).

A first difference is aesthetic: which one you like the most?

Another one is that the former concept and syntax help you convey the message that the function is giving back a value, something which is clear at the call site too (whereas at the call site you might not know if a parameter corresponding to an argument is passed by reference or not).

There are several differences between this two ways a function can have "consequences" at the caller site. For instance, you can only have one return value, whereas you can have as many paramters as you like.

Performancewise, complier optimizations can minimize the difference in performance, and maybe you should not worry (yet) about it.

SQL Server Performance ResultSet vs Output Parameter vs Return Value

Returning a scalar value is more efficient than a result set, the reason is result set carries lot more helper methods along with it, which makes it heavy thus increasing latency in transmission of the object from sql to C# code/routine.

In your method 3: You have used a variable to return the value this is more better than sending an out parameter since here you are cutting down on traverse of an object atleast in one route ( i.e., when invoking the stored procedure).

A result set is more flexible than an output parameter because it can return multiple rows (obviously), so if you need a result set then it's the only choice anyway.

To order the queries based on performance that goes as Method 3, Method 2 Method 1.

Hope this is helpful in understanding the concept.

When should I use out parameters?

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.



Related Topics



Leave a reply



Submit