At the Build 2016 Future of C# presentation Dustin Campbell and Mads Torgersen from Microsoft discussed a number of features planned for C#7.

Features and syntax subject to change

Before we begin it is important to note that all the features I will discuss are subject to change both in terms of syntax and indeed whether they make the cut for the final version so don’t be too surprised if there are a few changes still to come!

How can I play with these features?

So you want to play with these features not just read about them – how do you do it?

First up you will need to download the preview of Visual Studio 15.

I suggest if you just want to play with language features you use the new light weight installer which is very quick and downloads a lot less than the full Visual Studio Enterprise 15 preview so head over to https://www.visualstudio.com/en-us/downloads/visual-studio-next-downloads-vs – I’ll wait.

Now I regularly rebuild my machine & life’s too short to setup vm's etc (yep I’ll probably regret this decision) so I installed this alongside Visual Studio 2015.

This does seem to work without issue but as with any preview software anything could happen so your company laptop is probably not the place to experiment with this. You have been warned!

You have one more step to go before you can play with the new language features as by default these are disabled.

For example if you use the new digit separator feature and compile the project you will receive the following error message:

Feature 'digit separators' is experimental and unsupported; use '/features:digitSeparators' to enable.

Now you could turn on individual features by following these instructions but that sounds like a lot of work so let’s just enable them all. We can do this by going into project properties, Build tab and adding the following in the Conditional compilation symbol textbox:

__DEMO__;__DEMO_EXPERIMENTAL__

In fact most of the features seemed to work with either of these flags.

Ok done all that? Then we are ready to explore the new features.

Local functions

Local functions allow you to declare a function inside another function.

If you are a web developer you have probably done this in JavaScript many times.

To declare a local function in C# you can use the following syntax: ~~~csharp var z = 100;

int Add(int x, int y) { return x + y + z; }

var result= Add(1, 2); //103 ~~~

Here we have an inner function called Add that takes two parameters and unsurprisingly adds them together. Local functions will of course capture the state of any variables declared in outer scope so in this case we have access to the z variable making the end result 103 (1 + 2 + 100).

Although you can already accomplish something like the above using Lambda expressions I think this is much more readable – particularly if you have a function used in just one place or want to utilize recursive techniques.

Pattern matching

Pattern matching allows you to apply additional logic to certain types of constructs such as assignment and switch statements & short cut some tedious code.

For example it’s common to test the type of a variable and then assign it.

Now with pattern matching instead of having to do this in two steps we can accomplish this in one:

~~~csharp object someObj = DateTime.UtcNow;

if (someObj is DateTime someDate) { Console.WriteLine(someDate); } ~~~

The above tests if someObj is a DateTime type & if so then assigns the value to the someDate.

We can also use this technique in switch statements for example:

~~~csharp object someObj = DateTime.UtcNow;

switch (someObj) { case DateTime d: Console.WriteLine(d); break; } ~~~

In the presentation Dustin and Mads use this functionality for a more complex example of testing and assigning a variable:

~~~csharp if (p is Professor {Subject is var s, FirstName is "Scott"}){ //assigns subject to variable s if p is of type professor and firstname is "scott" } ~~~

Binary Literals

C# currently doesn’t have a good way to declare binary literal values with constructs such as the flag enums being probably the most commonly used construct for scenarios such as bit masks.

C#7 however allows you to declare binary literals in the following very readable way:

~~~csharp var five = 0b101; ~~~

Digit separators

When working with a large numbers digits can get hard to read very quickly and you really don’t want to be that guy or gal who accidently adds or misses an additional 0 to a constant!

C Sharp 7 allows you to utilize the underscore character to make numbers more readable e.g. nine million could be declared as follows:

~~~csharp var nineMillion = 9_000_000; ~~~

You can even use digit separators for binary values:

~~~csharp var five = 0b1_0_1; ~~~

Ref returns and ref locals

C# has always allowed us to pass parameters by reference. A variable of reference type does not contain the data but a reference to the data. For more information on this see the string example at see https://msdn.microsoft.com/en-AU/library/s6938f28.aspx.

Ref functionality has traditionally been restricted to parameter values but with C# 7 we can also return references to values using the ref keyword:

~~~csharp return ref x; ~~~

We can also declare local reference variables:

~~~csharp ref int y = ref foo.GetByRef("y"); ~~~

I’m wondering what the intention of this feature is or if its about addressing an odd limitation. The main use case I can see it being used for (as Thomas mentions in his article in further reading section) is performance scenarios to avoid copying large items.

Tuples

Important – Tuples are not included in the current preview although are demonstrated in the Build presentation.

There are many times you might want to group a set of variables together without wanting to create an actual class - probably the main time you might have come across this is when returning values from functions.

You might have used out parameters before which always feel a bit nasty or maybe C#'s existing Tuple class which feels even more clunky to use - example from https://msdn.microsoft.com/en-us/library/system.tuple(v=vs.110).aspx.

~~~csharp var population = new Tuple( "New York", 7891957, 7781984, 7894862, 7071639, 7322564, 8008278); ~~~

Ugh.

When you have set up your Tuple & want to access elements you have to access the properties using the unintuitive item1, item2 etc properties e.g.

~~~csharp var firstItem = population.Item1 ~~~

C# 7 introduces the much nicer syntax and uses compile time magic to make it possible to refer to items by property name.

In the presentation the following syntax is shown (remember this wont work with the current preview):

~~~csharp (int sum, int count) Tally(IEnumerable list){ return (0,0); } ~~~

Looks much nicer & easier to use – hopefully it will make it into C#7!

Future features

In Build the following features are also mentioned as being planned for the future:

  • Record types – this seems to be a way of simplifying the declaration of a collection of properties
  • Immutability – although C# offers some constructs that kind of offer immutability this gets complex quickly

Conclusion

C#7 does not seem a revolution but features such as pattern matching & local functions could change how a lot of everyday common code is written. Dustin & Mads also say that in future they plan to increase the cadence of C# releases so expect to see more and sooner!

Further reading