C# 7 Additions – Pattern Matching

C# 7 has started to introduce Pattern Matching. This is a concept found in functional programming, and although it isn’t fully implemented compared to F#, it is a step in that direction. Microsoft has announced they intend on expanding it in future releases.

Constant Patterns

The is keyword has been expanded to allow all constants on the right side of the operator instead of just a type. Previously, C#’s only valid syntax was similar to:

Now it is possible to compare a variable to anything which is a constant: null, a value, etc.

Behind the scenes, the is statement is converted to calling the Equals function in IL code. The following two functions produce roughly the same code (they call different overloads of the Equals function).

CheckIsNull

CheckEqualsNull

This can also be combined with other features allowing variable assignment through the is operator.

In Visual Studio Preview 4, the scoping rules surrounding variables assigned in this manner are more restrictive than in the final version. Right now, they can only be used within the scope of the conditional statement.

Switch Statements

The new pattern matching extensions have also extended and changed the use of case statements. Patterns can now be used in switch statements.

Like in previous versions, the default statement will always be evaluated last, but the location of the other case statements now matter.

In this example, case int n will never evaluate, because the statement above it will always be true. Fortunately, the C# compiler will evaluate this, determine that it can’t be reached and raise a compiler error.

The variables declared in patterns behave differently than others. Each variable in a pattern can have the same name without running into a collision with other statements. Just as before, in order to declare a variable of the same name inside the case statement, you must still explicitly enforce scope by adding braces ({}).

Pattern matching has a ways to go when compared to its functional language equivalent, but it is still a nice addition and will become more complete as the language evolves.

C# 7 Additions – Literals

A small, but nice chance in C# 7 is increased flexibility in literals. Previously, large numeric constants had no separator, and it was difficult to easily read a large number. For example, if you needed a constant for the number of stars in the observable universe (1,000,000,000,000,000,000,000), you’d have to do the following:

If you hadn’t caught the error, the constant is too short, and it’s difficult to tell looking at the numbers without a separator. In C# 7, it’s now possible to use the underscore (_) in between the numbers. So the previous example now becomes much easier to read, and it is easily recognizable the number is off.

The new version adds binary constants too. Instead of writing a constant in hex, or decimal, a constant can now be written like so:

C# 7 Additions – Throw Expressions

In previous versions, throwing exceptions had certain limitations where they could be used. Although not hampering, at times it caused additional work to validate and throw an exception, and C# 7 has removed much of the developer overhead for validation and execution.

Expressions

Previously to throw an exception in the middle of an expression there were really two options:

or

It is now possible to also throw an exception in the middle of an expression. Instead of checking for null, it is possible to throw as the second condition in the Null Coalescing Operator.

It is also possible in the Conditional Operator as well.

Expression Bodied Members

C# 6 added the ability to write a method with a single statement with a “fat arrow” (=>) and the statement. What used to be

can now be condensed to:

If you need a method stub, because you don’t know how to complete the method, and it was appropriate to use an Expression Bodied Member, you were left with two possibilities as throwing an expression wasn’t allowed by the compiler.

or

The first is error prone, because if program calls the method, there is no indication that it isn’t functioning properly. (Is null an expected return or an indicator of an error?) The second is better, but it is a little cumbersome that you must convert it to a standard function just to throw the exception. C# 7 solves this inconvenience and is now possible to throw exceptions in the Expression Bodied Member.