tags:

views:

309

answers:

11

When should we use an out parameter in C#?

For example

bool TryGetValue(out object value);

vs.

class ReturnType
{
      public bool Found {get;set;}
      public object Value {get;set;}
}

ReturnType TryGetValue();

Apart from reducing the number of lines of code, when should an out parameter to be used and when it should be returned as return type?

A: 

If object could be null. No need to instatiate then.

Greco
+3  A: 

You've nailed exactly the reason why it should be used. To reduce code complexity.

if (TryGetValue(myObj))
{
    [...]
}

is more tidy than

Result tryGetValueResult = TryGetValue();
if (tryGetValueResult.Found)
{
    [...]
}

It can also save on garbage when result needs to be a reference type.

jfclavette
Here's a related thread: http://stackoverflow.com/questions/134063/why-are-out-parameters-in-net-a-bad-idea
sgreeve
There is a thin line between less number of code and extensibility and elegance. Say if there are more than two out params, it would be wiser to have as return type
Ramesh
+2  A: 

If there's no general reason to encapsulate the multiple values together, other than for this call, then creating a separate type is probably over the top.

On the other hand, if you have multiple out parameters and a return value which all logically belong together (e.g. first name, last name, telephone number) then it would probably make sense to create an appropriate type (e.g. "Contact") and return that.

One alternative for the TryGetValue option is to use nullable value types, if the value in question is a value type. For instance, int.TryParse could have had a signature of:

int? TryParse(string text)

(with an overload taking an IFormatProvider of course).

Jon Skeet
+3  A: 

They are useful in the (rare) situation you need to return a value from a constructor. For example, the Mutex constructor has a boolean out parameter that is set to indicate if a new Mutex was created or it an existing mutex with a name already exists.

Sean
+4  A: 

Out can also be used for operations that might fail (typically found in methods starting Try*).

E.g. TryParse will return a bool indicating success/failure while using the out value as the result. This avoids having to throw exceptions.

Mark Simpson
A: 

I would vote for using the return type. Even though C# is not a functional language, I think it's good to aim at a functional programming style. Not for academic purity, but for the pragmatic benefits, where the behavior of every function is non-mysterious, without side-effects.

Corey Trager
Side effects and mysterious implies the function does something you didn't expect. If you pass something in an out position, isn't that exactly what you expected it to do?
Bill Wert
A: 

If you expect your function to just return a reference to a exiting object or create a new object then only out parameter should be used.

Ankit
A: 

I like to reserve return values for success indicators. Either simple true/false for success or something more complex like 0 for success and other values indicating what the error was.

This means that a programmer can test for success on every function you write. (of course, not all will, but the could)

This then requires out parameters to retrieve values from the function.

Khadaji
-1 - In .NET you should prefer exceptions to return codes in the general case. Occasionally there might be a function you expect to fail a reasonable proportion of the time in which case a return code would be appropriate; however this is not the usual case.
Greg Beech
+1  A: 

The out keyword enforces a couple of things via the compiler..
The caller doesn't have to initialize the param. The callee can't read from the param but has to write to it before exiting the method.

out more importantly makes the intent visible as the caller has to specify the out keyword when making a method call

You can use out when you need to return multiple values from a method (without stuffing and destuffing them from an object[]). (The section that loves to return bSuccess from every function would love the out keyword.)
In the example that you posted.. TryParse's primary return value is the success of the parse operation. So that is it's return value - but the most probable subsequent need would be to obtain the parsed object if it succeeded. So instead of making all callers do that step, TryParse saves you the trouble by giving it as an out param.. since it has already done that as part of the CanParse check.

Gishu
A: 

Out parameters are generally on the brittle side. Moving beyond the example, and looking at the problem in general: Bill Wagner's book "More Effective C#" describes quite a clever approach to this, it is also described in detail here.

The following code would work in this instance.

public class Tuple<T1,T2>
{
  public T1 First {get;private set;}
  public T2 Second {get; private set;}
  Tuple(T1 first, T2 second)
  {
    First = first;
    Second = second;
  }
}


using ComplexPair = Tuple<bool,object>;

public class SomeOtherClass 
{
  public ComplexPair GetComplexType ()
  {
    ...
    return new ComplexPair(true, new object);

  }
}
Martin Clarke
A: 

In my openion both are right, however I find returning a complex type more elegant especially if it is a generic type

ReturnType<T>

this gives more information about what to expect the value will be, so you don't guess the Value original type and do casting.

bashmohandes