What's New in C# 6.0

C# 6.0 – features worth a look

What's New in C# 6.0

I recently watched the Channel 9 video describing the main features of C# 6.0. Wow!

Updating a language is a tenuous task. I have watched the improvements of many languages over the years. I have seen many go from elegant to unusable. Usually, in the interest of backwards compatibility the standardizations bodies tend to get too clever for their own good.

Well, in this case, I am happy to report that did not happen.

The stated design goals that the team had (according to the linked to video above) were as follows.

  • No big concepts
  • Many small features
  • Clean up your code

After seeing the sort of syntactical sugar introduced in the last few iterations of the C# language I was encouraged by the last statement. And I was not disappointed.

Here are the features as presented in the video.

Click on the section headers to jump to that part of the video.

Getter-only Auto-properties

Auto-properties syntax has been extended to embrace the immutable object concept. You can now declare a read-only auto-property that can only be initialized at the point of declaration or via a constructor using the syntax you might expect.

public int X { get; } = 5; // read-only auto property initialization
public int Y ( get; }
// constructor initialization - no setter; set the backing field directly
public Point(int x, int y) {  X = x; Y = y; }

Using Static Members

The using clause gets a facelift allowing you to bring the static members of a class into scope or the members of an enumeration.

using static System.Math;
return Sqrt(2);
// Bringing enum members into scope
//   we do know the difference between Sunday and Blue don't we?
using static System.ConsoleColor;
var color = Blue;

String Interpolation

How many times have you looked at ToString() implementations and said to yourself – “there has to be a better way”. Well, now there is.

string.Format("({0}, {1})", X, Y);

becomes

$"({X}, {Y})";

Nice! Many languages have had this feature for years.

Expression-bodied Methods

With this feature the ToString() implementation becomes:

public override string ToString() => $"({X}, {Y})";

Elegant use of lambda syntax.

Expression-bodied Properties

With this feature a computed property goes from:

public double Dist
{
  get { return Sqrt(X * X + Y * Y); }
}

to this easier to read form:

public double Dist =>  Sqrt(X * X + Y * Y);

The lack of parens in the declared name provides the compiler with the hint that this is a property and not a method.

Nice.

Put These Together

At this point the video offers a mash up of these features in the form of an immutable Point class definition. The result is easy to read and terse. I love it.

using static System.Math;
public class Point
{
  public int X { get; }
  public int Y { get; }
  public Point(int x, int y) { X = x; Y = y; }
  public double Dist => Sqrt(X * X + Y * Y);
  public override string ToString() => $"({X}, {Y})";
}

And, yes, all of this works with structs too! The following is also valid syntax.

using static System.Math;
public struct Point
{
  public int X { get; }
  public int Y { get; }
  public Point(int x, int y) { X = x; Y = y; }
  public double Dist => Sqrt(X * X + Y * Y);
  public override string ToString() => $"({X}, {Y})";
}

Index Initializers

The Object initialization syntax has been extended to array indices. This is now possible:

public JObject ToJson() =>
  new JObject() { ["x"] = X, ["y"] = Y };

Null-condition Operators

Tired of all that null checking in methods that should be simple? Well, the “Elvis” operator comes to the rescue.

This:

public static Point FromJson(JObject json)
{
  if(json != null &&
     json["x"] != null &&
     json["x"].Type == JTokenType.Integer &&
     json["y"] != null &&
     json["y"].Type == JTokenType.Integer)
  {
    return new Point((int)json["x"], (int)json["y"]);
  }
  return null;
}

becomes this:

public static Point FromJson(JObject json)
{
  if(json?["x"]?.Type == JTokenType.Integer &&
     json?["y"]?.Type == JTokenType.Integer)
  {
    return new Point((int)json["x"], (int)json["y"]);
  }
  return null;
}

Remember nullable types? Now expressions like int? extend through their symbols to test for null. If they are null they simply resolve to null but do not raise an exception.

Look for the thread safe delegate invocation syntax discussion as well using this new operator towards the end of this video segment.

The nameof Operator

Have parameter names in strings? For example, when issuing an ArgumentNullException(“point”). Well, this new operator gives the refactoring engine a hint so that it will refactor the parameter names as well.

public Point Add(Point point)
{
  if(point != null)
  {
    return new ArgumentNullException(nameof(point));
  }
}

Exception Filters

Visual Basic and F# have had this feature for some time now. Don’t catch and re-throw if you cannot do something about the exception – right? That is what we teach.

Now there is syntax available to allow us to move further in that direction.

try
{
  ...
}
catch(Configurationexception e) when(e.IsSevere)
{
  ...
}
finally
{
  ...
}

Await in Catch and Finally

Previously, the await keyword could not be used in catch and finally blocks. But an efficient solution has been found so that the limitation could be lifted.

try
{
  ...
}
catch(Configurationexception e) when(e.IsSevere)
{
  await LogAsync(e);
}
finally
{
  await CloseAsync();
}

Learn More

http://github.com/dotnet/roslyn

 

Congratulations to Mads Torgersen and his team on a job well done.

Enjoy!

Leave a Reply

Your email address will not be published. Required fields are marked *