C# 6.0 – Declaration Expressions

[7/30/2015] This article was written against a pre-release version of C# 6.0. Be sure to check out the list of my five favorite C# 6.0 features for content written against the release!

[Update: 1 Oct 2014] It has been said that if something sounds too good to be true, it probably is. The adage apparently even applies to the proposed C# 6 features that I was excited about. I’m sad to say that it was announced today that declaration expressions would not be part of C# 6.

The C# 6.0 feature I’m probably the most excited about is declaration expressions. That the feature is listed as done on the language feature implementation status page and is included in the CTP only enhances my excitement.

Declaration expressions allow us to define local variables within an expression and scope them to the nearest block. As the CTP C# Features notes, this is particularly useful in conjunction with out parameters. Consider the traditional approach for working with an out parameter:

int result;
var myInt =
  int.TryParse("42", out result)
    ? result
    : 0;

I (like many others) hate this pattern, especially after having been so spoiled with F#’s approach of wrapping the call and returning both the status and parsed value as a tuple. Since C# probably won’t include usable Tuples anytime soon, declaration expressions provide a nice alternative as shown here:

var myInt =
  int.TryParse("42", out var result)
    ? result
    : 0;

In the previous snippet, we’ve moved the declaration of result into the TryParse call itself! Because I opted to use the conditional operator here, result is still visible within the parent context but other constructs (such as if statements) can limit the scope thus decreasing the risk of dealing with an uninitialized value. I call that a win.

Declaration expressions open up all sorts of other possibilities, too. For instance, the CTP notes show how they can improve the developer experience in cases where expressions are required using query expressions as an example:

var myInts =
  from ps in
    (from s in strings
     select (int.TryParse(s, out var result) ? result : (int?)null))
  where ps.HasValue
  select ps.Value;

Without declaration expressions, the preceding query expression would have required us to wrap the parsing logic within another function but because we can include the result variable definition inline, such a query is possible.

Finally, how many times have you written something like this?

var myStr = myObj as MyType;
if (myStr != null)
{
  ...
}

The as operator pattern doesn’t bother me nearly as much as the out parameter pattern but it still feels dirty since it exposes the variable outside of where it’s actually needed. Declaration expressions let us make this a bit prettier, again by moving the declaration inline with the if statement as follows:

if ((var myStr = myObj as string) != null)
{
  ...
}

I like this approach a bit better than the traditional approach not because it lets us write less code (it doesn’t, really since the lines are just merged) but because it limits the scope of myStr.

So yeah, I’m pretty excited about this feature and think it’s safe to assume that I’ll be adopting it just as quickly as I do primary constructors once it’s generally available.

Advertisements