What’s New in C# 6.0
C# 6.0, which shipped with Visual Studio 2015, features a new-generation compiler, completely written in C#. Known as project “Roslyn,” the new compiler exposes the entire compilation pipeline via libraries, allowing you to perform code analysis on arbitrary source code. The compiler itself is open source, and the source code is available at https://github.com/dotnet/roslyn.
In addition, C# 6.0 features several minor but significant enhancements, aimed primarily at reducing code clutter.
The null-conditional (“Elvis”) operator (see “Null Operators”) avoids having to explicitly check for null before calling a method or accessing a type member. In the following example, result
evaluates to null instead of throwing a NullReferenceException
:
System.Text.StringBuilder sb = null;
string result = sb?.ToString(); // result is null
Expression-bodied functions (see “Methods”) allow methods, properties, operators, and indexers that comprise a single expression to be written more tersely, in the style of a lambda expression:
public int TimesTwo (int x) => x * 2;
public string SomeProperty => "Property value";
Property initializers (Chapter 3) let you assign an initial value to an automatic property:
public DateTime TimeCreated { get; set; } = DateTime.Now;
Initialized properties can also be read-only:
public DateTime TimeCreated { get; } = DateTime.Now;
Read-only properties can also be set in the constructor, making it easier to create immutable (read-only) types.
Index initializers (Chapter 4) allow single-step initialization of any type that exposes an indexer:
var dict = new Dictionary<int,string>()
{
[3] = "three",
[10] = "ten"
};
String interpolation (see “String Type”) offers a succinct alternative to string.Format
:
string s = $"It is {DateTime.Now.DayOfWeek} today";
Exception filters (see “try Statements and Exceptions”) let you apply a condition to a catch block:
string html;
try
{
html = await new HttpClient().GetStringAsync ("http://asef");
}
catch (WebException ex) when (ex.Status == WebExceptionStatus.Timeout)
{
...
}
The using static
(see “Namespaces”) directive lets you import all the static members of a type so that you can use those members unqualified:
using static System.Console;
...
WriteLine ("Hello, world"); // WriteLine instead of Console.WriteLine
The nameof
(Chapter 3) operator returns the name of a variable, type, or other symbol as a string. This avoids breaking code when you rename a symbol in Visual Studio:
int capacity = 123;
string x = nameof (capacity); // x is "capacity"
string y = nameof (Uri.Host); // y is "Host"
And finally, you’re now allowed to await
inside catch
and finally
blocks.