5 New Things In C# 6.0

shutterstock_159124214

Now almost fifteen years old, C# continues to improve with each major release. If you use any version of Visual C# 2015, you have access to C# 6.0 and its many new features. I’ve chosen to focus on five of the most important or useful ones.

Null-Conditional Operator

I rate this as probably the most important new feature. Every C# programmer has probably experienced a Null-reference exception at some point, usually by forgetting to new a reference variable. For instance:

[csharp]

var List<String> list;

list.Clear(); // it’s null then bam!

[/csharp]

A compiler generally won’t allow that sort of thing to go through; but if it did, it would produce an exception along the lines of, “Unhandled Exception: System.NullReferenceException: Object reference not set to an instance of an object.”

It’s customary to check that the reference variable is not null before passing parameters to a method:

[csharp]

void CheckList(List<String list){

// other stuff

if (list != null){

list.Clear();

}

}

[/csharp]

The new to C# 6.0 Null Conditional operator ?. does the “if” for you:

 

[csharp]

void CheckList(List<String list){

// other stuff

list?.Clear();

}

[/csharp]

if it’s null, it doesn’t call list.Clear(). You can chain multiple ?. For example, here’s how the result of a method might be called:

[csharp]

if (p.GetData()?.ProcessDataOK()?==true) {

// do something.

}

[/csharp]

This reminds me very much of optionals in Swift, as does this example:

[csharp]

using static System.Console;

internal class Program

{

private static string StopCompilerObjecting()

{

return null;

}

private static void Main(string[] args)

{

String s= StopCompilerObjecting(); // assign a null

var p = s.Length;

WriteLine( p );

}

}

[/csharp]

The StopCompilerObjecting() is a way to assign a null to a string without a compiler error. Running this generates a null-reference exception, as you’d expect. You may wonder why there’s no Console; prefixing the WriteLine( p ); in a new twist, you can now use the word static in using clauses, negating the need for Console.

As an experiment, change the second line in the Main() body to:

[csharp]

var p=s?.Length;

[/csharp]

It outputs nothing, not even an exception! Behind the scenes, I guess it’s checking HasValue. How do I know this? Because Intellisense shows HasValue and Value. In other words, s?.Length returns an Int?, not an Int. Remember that; it’s bound to come up as an interview question.

Auto Initializing Properties

Prior to C# 6.0, when you used properties, you could initialize them only when creating an instance by calling the constructor, or explicitly assigned in the constructor. Now you can assign a default value where the property is defined.

Here’s an example of the old way. As Make only has a get; it’s read-only:

[csharp]

using static System.Console;

internal class Program

{

private static void Main(string[] args)

{

var Car = new AutoMobile();

WriteLine($"Make: {Car.Make} Model: {Car.Model}");

}

public class AutoMobile

{

public string Make { get; }

public string Model { get; set; }

&nbsp;

public AutoMobile()

{

Make = "Car Company";

Model = "Basic Model";s

}

}

}

[csharp]

(An additional note: I’ve used another new C# 6.0 feature. Instead of placeholders in the WriteLine statement—it would have been Console.WriteLine("Make: {0} Model: {1}",car.Make,Car.Model)—the $"" notation has the string interpolated, i.e. it calls String.Format() behind the scenes. The values in the curly braces are evaluated. Note you can’t use verbatim (@ prefixed) strings with string interpolation. <a href="https://msdn.microsoft.com/en-GB/library/dn961160.aspx">Here are some more details</a> on string interpolation.)

By using auto property initializers, there’s no longer a need for the constructor for the properties. Here’s the class AutoMobile now:

[csharp]

public class AutoMobile

{

public string Make { get; }       = "Car Company";

public string Model { get; set; } = "Basic Model";

}

[/csharp]

If you do use a constructor, you can now assign to a read-only property in the constructor body, as well.

Expression Based Functions and Properties

These tie in with the auto property initializers, using a Lambda function (i.e., an anonymous function), called in the usual way by the fat arrow =>, to provide a value. The example below rolls Ten x Six side dice:

[csharp]

public static int RollaDice(int x) => (int) r.Next(x) + 1;

public static Random r = new Random();

&nbsp;

private static void Main(string[] args)

{

for (var i = 0; i < 10; i++)

{

WriteLine(Dice(6));

}

}

[/csharp]

RollaDice() is only static because I’m calling it from main; Random r is likewise static, but I only ever want one instance of a random number generator, so I always declare it static, even in an instance of a class.

The statement version of this lets you run a single statement. If ErrorObj is an instance of some logging class, then this logs an error:

[csharp]

public void LogError(string msg) => ErrorObj.WriteLine(msg);

[/csharp]

Plus you can use it to provide a value for a property.

Exception Filters

In the catch (ExceptionType) of a try..catch statement, you can now add when(bool condition) to the catch to add extra granularity to exception handling. This rather contrived example lets you decide whether the exception from a divide by zero is suppressed or reported:

[csharp]

using System;

using static System.Console;

internal class Program

{

public static int TryDivByZero(int denominator,bool allow=false)

{

try

{

return 4 / (denominator – 1);

}

catch (DivideByZeroException) when (allow)

{

return 0;

}

catch (Exception)

{

WriteLine("Divide by zero error");

return -1;

}

}

&nbsp;

private static void Main(string[] args)

{

var res=TryDivByZero(1,true);

WriteLine(res);

}

}

[/csharp]

When allow is true, it silently returns 0; otherwise it says Divide by Zero error and returns -1.

New line breaks in Strings

While some might see this as a trivial addition, it can be quite handy in decluttering long string assignments:

[csharp]

private static void Main(string[] args)

{

var longstring = @"Hello

World";

WriteLine(longstring);

}

[/csharp]

You can break strings across lines, but they have to be verbatim strings i.e. @ prefixed strings. Watch out for those spaces or tabs now, because they’re included in the string, as well. The output from running this is:

[csharp]

Hello

World

[/csharp]

Conclusion

Yes, many of the features new in C# 6.0 are syntactic sugar, but don’t underestimate them; reducing the source size and eliminating boilerplate makes the code easier to read and understand. This is also the first C# to use Roslyn, the compiler technology that gives you access to the compilation process. Want to see what’s in the works for C# 7.0? Watch the design notes page on Github and use the C# 7.0 filter.

Image Credit: YanLev/Shutterstock.com

Comments

One Response to “5 New Things In C# 6.0”

January 21, 2016 at 6:20 am, Michael said:

What, no mention of the nameof operator? There are a lot of interesting developments with C# 6.0, not least of which is a crazy FAST compiler, rewritten “accidentally” in F#. The nameof operator is hands down one of the most useful things I think I would use. There are other compelling features too, but nameof saves a lot of time diving deep into reflection when just to find a property, method, or other name.

Reply

Post a Comment

Your email address will not be published.