Skip to content

6.0

C# 6.0, released with .NET Framework 4.6 in July 2015, introduced several syntactic sugar features that made the language more concise and expressive. These features helped reduce boilerplate code and made certain patterns more readable. Here are some of the key features introduced in C# 6.0, along with examples and comparisons to earlier versions of C#:

1. String Interpolation

String interpolation allows you to embed expressions directly within string literals using the $ character, making the creation of formatted strings more readable.

C# 6.0

var name = "Alice";
var greeting = $"Hello, {name}!";
Console.WriteLine(greeting);  // Output: "Hello, Alice!"

C# < 6.0 Previously, you had to use string.Format, concatenation, or other methods to compose strings, which was less readable.

var name = "Alice";
var greeting = string.Format("Hello, {0}!", name);
// or
var greeting = "Hello, " + name + "!";
Console.WriteLine(greeting);

2. Null-conditional Operators (?. and ?[])

Null-conditional operators allow you to safely access members and elements of an object that might be null, reducing the amount of code needed for null checks.

C# 6.0

string[] array = null;
var length = array?.Length;  // No NullReferenceException, 'length' will be null
Console.WriteLine(length);  // Output: ""

C# < 6.0 Before C# 6.0, you had to explicitly check for null to avoid NullReferenceException.

string[] array = null;
var length = (array != null) ? array.Length : (int?)null;
Console.WriteLine(length);

3. Expression-bodied Members

Expression-bodied members allow properties, methods, and read-only properties to have their bodies defined as an expression, making the syntax more concise for simple implementations.

C# 6.0

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string FullName => $"{FirstName} {LastName}";
}

C# < 6.0 Previously, even simple properties or methods required a full body with a return statement.

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string FullName
    {
        get { return FirstName + " " + LastName; }
    }
}

4. Auto-property Initializers

Auto-property initializers allow you to directly initialize auto-implemented properties at their declaration point, simplifying the initialization of properties.

C# 6.0

public class Person
{
    public string Name { get; set; } = "Unknown";
}

C# < 6.0 Before C# 6.0, property initialization required a constructor or field initialization.

public class Person
{
    public string Name { get; set; }
    public Person()
    {
        Name = "Unknown";
    }
}

5. Nameof Expressions

The nameof operator provides a safe way to obtain the name of a variable, type, or member as a string, making your code more refactor-safe.

C# 6.0

public void NotifyPropertyChanged(string propertyName)
{
    Console.WriteLine($"Property changed: {propertyName}");
}

NotifyPropertyChanged(nameof(Name));

C# < 6.0 Previously, you had to use string literals, which could lead to errors during refactoring.

public void NotifyPropertyChanged(string propertyName)
{
    Console.WriteLine($"Property changed: {propertyName}");
}

NotifyPropertyChanged("Name");