Randomize

Richard Tallent’s occasional blog

A replacement for evil outs

I was reading a post by Jon Skeet and he mentioned the evil of using “out” parameters.

Anyone with a functional programming background understands what he’s referring to here — pure functions should have no side effects, they should only return a value.

The problem is, the world isn’t pure, and it’s quite common to need to return multiple results.

Probably the most common example in C# is the “TryGetValue()” pattern:

public bool TryGetValue(
  TKey key,
  out TValue value
)

C# 6 allows us to call this in a way that declares the “out” at the same time as the TryGetValue call (where before, we would need to declare the output variable first):

if(dict.TryGetValue("mykey", var myoutput) {
  Response.Write(myoutput);
}

Jon makes the valid point that this will only encourage “out” parameters, which should really only be the exception to the rule. A more functional approach would be:

public struct TryGetValueResult(bool success, T value) {
  public bool Success { get; } = success;
  public T Value { get; } = value;
}

var result = dict.TryGetValue("mykey");
if(result.Success) {
  Response.Write(result.Value);
}

Much cleaner from a functional standpoint, but still has that annoying declaration of a variable I’ll probably only use within the “if” block. (I could use “using,” but the line count is the same and I’m retreating one more brace level).

But what if we could do the following:

if((var result = dict.TryGetValue("mykey")).Success) {
  Response.Write(result.Value);
)

Essentially, allow variable declarations to create a variable scoped to the “if/else” block, assign a value, and return the value.

I don’t know if C# 6 would support this type of use, but if it would, it might be the best of both worlds.


Share

comments powered by Disqus