What’s New in C# 6.0

Introduction

Visual Studio 2015 will be officially RTM on July 20th, Microsoft announced. With it comes a new version of the .NET framework (actually, two), .NET 5.0, and inside of it, support for a new version of the C# language, C# 6.0. Yeah, the numbers don’t match, keep that in mind! Winking smile

If you are curious, Visual Studio 2015 will also include .NET 4.6. This will provide a migration path for those of us who are stuck with .NET 4.x code and can’t afford the breaking changes that .NET 5 will introduce. More on this in a future post.

For the moment, I am going to talk about what’s new in C# 6.0, in no particular order. Some of you may be familiar with parts of it, and some might even be expecting a bit more, but unfortunately, some features that were previously announced didn’t make it to the final version.

Auto-Property Initializers

It is now possible to provide an initial value for auto-implemented properties without resorting to a custom constructor. Here’s how, in two examples:

public class MyClass
{
    public int MyNumericProperty { get; set; } = 1;
    public bool MyBooleanOtherProperty { get; set; } = (MyNumericProperty > 0);
}

Did you notice how we can even use simple expressions in the initialization block? Pretty cool!

Getter-Only Auto-Properties

Similar to the previous example, we can now have getter-only properties, that is, without any kind of setter. We just need to provide an initialization value:

public class Math
{
    public static double PI { get; } = 3.14159265359;
}

Alternatively, we can define its value in a constructor:

public class Math
{
    public static double PI { get; }
 
    static Math()
    {
        PI = 3.14159265359;
    }
}

Expression-Bodied Methods and Properties

Not sure of the actual interest of this one, but, hey, it’s here: the ability to supply the body for properties and methods from simple expressions.

public class MyClass
{
    public int Add(int a, int b) => a + b;
 
    public string TimeOfDay => DateTime.Now.TimeOfDay;
}

nameof Expressions

nameof expressions avoid the need to hardcode names or use complex reflection or LINQ expression tricks. It’s better to show it in action:

void ThrowArgumentNullExceptionUsingNameOf(string param1)
{
    throw new ArgumentNullException(nameof(param1));    //"param1"
}
 
var className = nameof(MyClass);                    //"MyClass"
 
var propertyName = nameof(myInstance.Property);    //"Property"

Exception Filters

This is about the ability to filter exceptions in a catch block based on more than the exception class itself:

try
{
    //…
}
catch (MyException ex) if (ex.Code == 42)
{
    //…
}
catch (MyOtherException ex) if (Check(ex))
{
    //…
}

Notice that you can use methods in the filter clause, not just simple comparisons.

String Interpolation

This is one of my favorites: adding field, variable and method calls in the middle of a string, and having it interpreted at runtime:

var variable = $"This is i: {i}";
var property = $"A property: {this.Property}";
var method = $"Filename: {Path.GetFullPath(filename)}";
var format = $"Short date: {DateTime.Now:d}";

Very similar to String.Format, but easier to use.

Null-Conditional Operator

Another personal favorite! No need for repeated null checks in deep property accesses or event handlers, the compiler takes care of it for us:

var p = myInstance?.myProperty?.myNestedProperty;
 
public event EventHandler MyEvent;
 
public void OnMyEvent(EventArgs e)
{
    this.MyEvent?.Invoke(this, e);
}

If either myInstance or myProperty are null, null will be returned. It even works for events, as you can see.

Using Static Members

Besides bringing namespace types into context, using can now be used to do the same with static methods! For instance, take Console.WriteLine:

using WriteLine = System.Console.WriteLine;
//static method WriteLine only
WriteLine("Hello, World");
 
 
using System.Linq.Enumerable;
//all extension methods of Enumerable
var numbers = new [] { 1, 2, 3 };
var even = numbers.Where(x => (x % 2) == 0);

This will come in handy, to avoid type clashes. We just import the methods we’re interested in.

Index Member Syntax

A new notation for creating dictionary instances is introduced:

var dict = new Dictionary<int, string>
{
    [1] = "one",
    [2] = "two"
};

Async in Catch and Finally Blocks

Using async in a catch or finally block is now valid:

try
{
    //...
}
catch (Exception exception)
{
    await LogAsync(exception);
}
finally
{
    await ReleaseAsync();
}

Extension Add Methods in Collection Initializers

Starting with C# 4 (.NET 4), we could use an explicit enumeration syntax for creating collections (actually, any kind of classes that provided an Add method with a compatible parameters). Now extension methods are supported as well:

public static void Add(this ICollection<string> col, int i)
{
    col.Add(i.ToString());
}
 
var col = new List<string>{ 1, 2, 3 };

Here we are creating a List of strings, but we have an extension method that knows how to add integers to collections of strings.

Conclusion

All weighed up, there are some nice additions, others I don’t really see the point, but eventually I may.

You can read everything about it in the Roslyn site at GitHub: https://github.com/dotnet/roslyn and https://github.com/dotnet/roslyn/wiki/Languages-features-in-C%23-6-and-VB-14.

                             

7 Comments

  • I think nameof(myInstance.Property) would just return "Property" and not "myInstance.Property"?

  • Sea Sharp:
    Thanks, you are right! Updated! ;-)

  • I believe declaration expressions were dropped in C# 6, and they're looking at putting them in C# 7.

  • I believe Declaration Expressions were removed.

    Also, am I the only one who doesn't see the point of Index Initializers? It's not terser, it's not easier to read, and they are less composable when it comes to nesting and if you have to introduce linebreaks between keys and values because of resulting line length.

    I guess they might be more "pure" since it uses indexers instead of the "magic" .Add() method, but since they also added Extension Add Methods, the need is much reduced.

  • Nelson and googly:
    Thanks, you are right: declaration expressions are not part of the standard.
    Post updated!

  • Parameterless struct constructors were dropped as well.

  • Thomas:
    True, thanks!

Add a Comment

As it will appear on the website

Not displayed

Your website