27

I have a method that has several overrides. In one of the more expanded overrides, I want to return an OUT parameter but not in my simpler overrides. For example:

public bool IsPossible(string param1, int param2)
public bool IsPossible(string param1, int param2, out bool param3)

The way I am currently achieving this, is like so:

public bool IsPossible(string param1, int param2) {
    bool temp;
    return IsPossible(param1, param2, out temp);
}

Is there a better way to achieve this? Can I (or should I) use a null-able out parameter?

Community
  • 1
  • 1
Derek Hunziker
  • 12,996
  • 4
  • 57
  • 105

6 Answers6

19

That looks fine to me. A out cannot be optional for technical reasons (it needs to point to a valid instance).

Lucero
  • 59,176
  • 9
  • 122
  • 152
  • Having a hard time believing the reason for not supporting this is technical more than marketing priorities. Seems the compiler could just create a temp location just as your example--and also for Refs by init'ing with Default(T). Notably, "out/ref (inout)" arguments are [supported in SQL Server](http://stackoverflow.com/questions/3267523). – crokusek Jan 20 '14 at 20:37
  • 1
    It's worth to mention, that in C# 7.0 you can use Discards with Underscore sign. Read more here: https://stackoverflow.com/a/42924200/1319086 – Jonatan Dragon Feb 01 '19 at 12:52
  • VB.net does it. C# should automatically allow out/ref to be optional, and fill in a dummy variable when needed in the background. – Brain2000 Apr 08 '22 at 15:12
17

Since C# 7.0 you can pass a Discard (_) into the method:

return IsPossible(param1, param2, out _);

See: https://learn.microsoft.com/en-us/dotnet/csharp/discards

aaroncatlin
  • 3,203
  • 1
  • 16
  • 27
7

OP:

Can I (or should I) use a null-able out parameter?

A nullable out parameter won't do you much good. This:

public bool IsPossible( string param1, int param2, out bool? param3 )
{
  ...
}

doesn't make param3 optional. It changes the semantics of what param3 is. A bool? (aka Nullable<bool>) widens the domain of param3 from 2 values ( true and false ) to 3, adding a third value (null), usually interpreted as missing/unknown. The caller still must supply all three arguments.

Overloading IsPossible() by providing an overload -- the "don't care" scenario -- that discards the reference parameter is the proper solution.

Nicholas Carey
  • 71,308
  • 16
  • 93
  • 135
4
A 'ref' or 'out' parameter cannot have a default value.

The way you've done it is just fine. Sorry, no silver bullet.

agent-j
  • 27,335
  • 5
  • 52
  • 79
4

Personally I think it is fine "as is". Another approach, though, is to return a composite return value (perhaps an immutable struct with 2 properties); that avoids the fact that some people avoid out. I am not one of those people :p

Re the question; indeed, out/ref can't be optional.

If you wanted to get unnecessarily fancy you could give the conposite return-type a conversion to bool to allow implicit if tests.

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
0

Yes, Nullable variables are great. You would then do something like this.

public bool? IsPossible(string param1, int param2);

var ans = IsPossible("Parm1", 1);
if (ans.HasValue)
{
   //working.
 }
Jethro
  • 5,896
  • 3
  • 23
  • 24
  • I don't find this API style hugely obvious to the caller, personally. Subjective, though. – Marc Gravell Jun 30 '11 at 18:56
  • What do you mean obvoius to the caller? – Jethro Jun 30 '11 at 18:58
  • 4
    well, for starters - there were previously 4 possible outcomes; there are now 3; what are they equivalent of, etc? what does it mean for IsPossible to be null? vs non-null but false? presumable true means "yes it is possible", but the other two are less clear-cut to me. – Marc Gravell Jun 30 '11 at 19:59