C#7: Out Variables

Last time, we started to look at the new features introduced in C#7. Here is a quick refresher of just what those features are:

In this post, we will look at one of the simplest additions to the C# language; out variables.

int dummy

How often have you written code like this?

Or this?

Sometimes you use the out value retrieved, sometimes you do not, often you only use it within the scope of the condition. In any case, there is always the variable definition awkwardly hanging out on its own line, looking more important than it really is and leaving space for it to accidentally get used before it has been initialized. Thankfully, C#7 helps us tidy things up by allowing us to combine the variable definition with the argument.

Using the out variable syntax, we can write this:

In fact, we do not even need to declare the type of the variable explicitly. While often we want to be explicit to make it clear that it matters (and to ensure we get some compile time checking of our assumptions), we can use an implicitly typed variable like this:

In Conclusion

out variables are part of a wider set of features for reducing repetition (in written code and in run-time execution), and saying more with less (i.e. making it easier for us to infer intent from the code without additional commentary). This is a very simply addition to C# syntax, yet useful. Not only does it reduce what we need to type, it also improves code clarity (in my opinion), and reduces the possibility of silly errors like using a variable before it has been initialized, or worse, thinking that it being uninitialized was a mistake and hiding a bug by initializing it.

Until next time, if you would like to tinker with any of the C#7 features I have been covering, I recommend getting the latest LINQPad beta or Visual Studio 2017 RC.


C#6: String Interpolation

Continuing the trend of my recent posts looking at the new features of C#6, this week I want to look at string interpolation.

Prior to C#6, string interpolation (or string formatting) was primarily the domain of the .NET framework and calls like string.Format() and StringBuilder.AppendFormat()1 as in the following example:

With string interpolation in C#6, this can be written as:

This is a little easier to read while also reducing what has to be typed to achieve the desired result. The contents of the braces are evaluated as strings and inserted into the resultant string. Under the hood, this example compiles down to the same string.Format call that was made in the earlier example. The same composite formatting power is there to specify things like significant figures and leading zeroes. If you need a culture-invariant string, there is a handy static method in the new System.FormattableString class called Invariant(). If you wrap your string with this Invariant() method, you will get the string formatted against the invariant culture.


Of course, to end the story there without discussing the compiler magic would do a disservice to this new feature. In the example above, the result of the interpolation was stored in a variable with type var. This means the type is inferred by the compiler, which infers string and then performs appropriate compiler operations to turn our interpolated string into a call to string.Format(). This means that we don't have to do anything else to use this feature and get formatted strings. However, we can make the compiler do something different by rewriting the line like this2:

We have now specified that we are using a variable of type FormattableString. With this declaration, the compiler changes its behavior and we get a FormattedString object that represents the interpolated string. From this object, we can get the Format string that could be passed to a call that takes a format string, such as string.Format() (there are several others in types like Console, StringBuilder, and TextWriter). We can also retrieve the number of arguments3 in the string using ArgumentCount, and use GetArgument() and GetArguments() to retrieve the values of those arguments. Using a combination of Format and GetArguments(), we can pass this information to a different call that might reuse or extend it to produce a different message. Finally, we can use the ToString() call to specify an IFormatProvider, allowing us to format the string according to a specific culture.

By telling the compiler that we want a FormattableString we get all this extra information to use as we see fit. If you look at the arguments using either of the Get.. methods, you will see that the values have already been evaluated, so you can be assured that they won't change as you process the string. I'm sure there are situations where you might find this additional access to the formatting invaluable, such as when creating compound error messages, or perhaps doing some automatic language translation.

In conclusion…

There's not much else for me to say about C#6's string interpolation except to highlight one gotcha that I have hit a couple of times. The next two examples should illustrate appropriately:

Here is what these two examples will output:

It's hard to argue with either of them, after all, they both wrote an interpretation of DateTime.Now to the console, but the first one is perhaps a more useful output4.

So why did the second example not work? You may have already spotted the answer to that question, especially if you're a VB programmer; it's the $ at the start of the first example's string.  This $ tells the compiler that we are providing a string for interpolation. It's an easy thing to miss and if you forget it (or perhaps, in rare cases, add it erroneously) you'll likely only spot the mistake through thorough testing5 or customer diligence6. As always, learn the failure points and work to mitigate them with code reviews and tests. I suspect the easiest mitigation may be to always use the interpolation style strings unless a situation demands otherwise.

And that's it for this week. What do you think of the new string interpolation support? Will you start using it? If not, why not? Do you have any cool ideas for leveraging the additional information provided by FormattableString? Please share in the comments.

If you're interested in my other posts on some of the new things introduced by C#6, here are links to posts I have written thus far:

  1. The + operator can be used in conjunction with ToString() but it can get messy to read and is very hard to localize 

  2. We could also cast the interpolated string to FormattableString and leave the variable as var

  3. Each inserted value is an argument 

  4. Except when providing examples in a blog 

  5. Unit tests or otherwise 

  6. Write automated tests and test manually; let's not use customers as QA