What is New in C# 6.0

Get a quick glance at what's new in C# 6.0. Here are the features with easy to understand examples.

static types as using

So, we are all quite familiar with this notion of accessing static class members using the qualification first. It is not required now. Importing static using can save the day. For example, before C# 6.0, we had to access ReadKey(), WriteLine() methods of the Console class by explicitly defining the static class qualifier.

  1. using System;  
  2.   
  3. namespace NewInCSharp  
  4. {  
  5.     class Program  
  6.     {  
  7.         static void Main(string[] args)  
  8.         {  
  9.             MySelf.WhoAmI();  
  10.             Console.ReadKey();  
  11.         }  
  12.     }  
  13.   
  14.     static class MySelf  
  15.     {  
  16.         public static void WhoAmI()  
  17.         {  
  18.             Console.WriteLine("I'm Fizz!");  
  19.         }  
  20.     }  
  21. }  
In C# 6.0, we can get rid of the qualifiers just by importing the static types in the namespace like the following code snippet:
  1. using static System.Console;  
  2. using static NewInCSharp.MySelf;    /* Magic happens here */  
  3.   
  4. namespace NewInCSharp  
  5. {  
  6.     class Program  
  7.     {  
  8.         static void Main(string[] args)  
  9.         {  
  10.             WhoAmI();  
  11.             ReadKey();  
  12.         }  
  13.     }  
  14.   
  15.     static class MySelf  
  16.     {  
  17.         public static void WhoAmI()  
  18.         {  
  19.             WriteLine("I'm Fizz!");  
  20.         }  
  21.     }  
  22. }  
String interpolation

You can now forget using placeholders in strings to replace them with real values. C# 6 has a new feature called string interpolation using which you can now directly write your arguments instead of referring them with placeholders inside a string. You can also do whatever you would have done previously with String.Format() function.

Before C# 6.0
  1. using System;  
  2. using System.Collections.Generic;  
  3. using static System.Console;  
  4.   
  5. namespace NewInCSharp  
  6. {  
  7.     class Program  
  8.     {  
  9.         private static void Main(string[] args)  
  10.         {  
  11.             string name = "Murphy Cooper";  
  12.             string planet = "Cooper Station";  
  13.   
  14.             WriteLine("{0} is actually named after {1}", planet, name);  
  15.   
  16.             ReadLine();  
  17.         }  
  18.     }     
  19. }  
After C# 6.0
  1. using System;  
  2. using System.Collections.Generic;  
  3. using static System.Console;  
  4.   
  5. namespace NewInCSharp  
  6. {  
  7.     class Program  
  8.     {  
  9.         private static void Main(string[] args)  
  10.         {  
  11.             string name = "Murphy Cooper";  
  12.             string planet = "Cooper Station";  
  13.   
  14.             /* Magic happens here */  
  15.             WriteLine($"{planet} is actually named after {name}");  
  16.   
  17.             ReadLine();  
  18.         }  
  19.     }     
  20. }  
Again these are some string formatting examples which I missed in the video:
  1. string name = "Sammy Jenkins";  
  2. double salary = 1000;  
  3.   
  4. WriteLine($"{name}'s monthly salary is {salary:C2}");   
  5. WriteLine($"Man! This {name} is kind of a {(salary >= 1000 ? "rich guy" : "poor guy")}");  
  6.   
  7. /*Output:  
  8.     Sammy Jenkins's monthly salary is $1000.00 
  9.     Man! This Sammy Jenkins is kind of a rich guy 
  10. */  
Dictionary Initializers

C# 6.0 changed the way you can initialize Dictionary. Previously on C# 5 you would have to initialize the Dictionary with this type of syntax, {"Key", "Value"}. Now in C# 6.0 you can just place the key between two curly brackets ["Key"] and then set the value of the key ["Key"] = "value"; , just like you set value for other types of variable. This new syntax is more friendlier than before.

Before C# 6
  1. using System.Collections.Generic;  
  2. using static System.Console;  
  3.   
  4. namespace NewInCSharp  
  5. {  
  6.     class Program  
  7.     {  
  8.         private static void Main(string[] args)  
  9.         {  
  10.             Dictionary alien = new Dictionary()  
  11.             {  
  12.                 {"Name""Fizzy"},  
  13.                 {"Planet""Kepler-452b"}  
  14.             };  
  15.   
  16.             foreach (KeyValuePair keyValuePair in alien)  
  17.             {  
  18.                 WriteLine(keyValuePair.Key + ": " + keyValuePair.Value + "\n");  
  19.             }  
  20.   
  21.             ReadLine();  
  22.         }  
  23.     }     
  24. }  
In C# 6.0
  1. using System.Collections.Generic;  
  2. using static System.Console;  
  3.   
  4. namespace NewInCSharp  
  5. {  
  6.     class Program  
  7.     {  
  8.         private static void Main(string[] args)  
  9.         {  
  10.             /* The new and friendly syntax */   
  11.             Dictionary alien = new Dictionary()  
  12.             {  
  13.                 ["Name"] = "Fizzy",  
  14.                 ["Planet"] = "Kepler-452b"  
  15.   
  16.             };  
  17.   
  18.             foreach (KeyValuePair keyValuePair in alien)  
  19.             {  
  20.                 WriteLine(keyValuePair.Key + ": " + keyValuePair.Value + "\n");  
  21.             }  
  22.   
  23.             ReadLine();  
  24.         }  
  25.     }     
  26. }  
Auto-Property Initializers

C# 6.0 came with a new concept of initializing class properties inline rather than initializing them within the type's constructor. Another handy technique is, if you want to make the setter of a property private to block users from setting value in the property by an instance, you can just declare a getter only property. For example,

Before C# 6
  1. using static System.Console;  
  2.   
  3. namespace NewInCSharp  
  4. {  
  5.     class Program  
  6.     {  
  7.         static void Main(string[] args)  
  8.         {  
  9.             Employee employee = new Employee();  
  10.   
  11.             WriteLine("Name: " + employee.Name + "\nSalary: " + employee.Salary);  
  12.   
  13.             ReadKey();  
  14.         }  
  15.         public class Employee  
  16.         {  
  17.             public string Name { getset; }   
  18.             public decimal Salary { getset; }  
  19.             public Employee()  
  20.             {  
  21.                 /* Initializing property through constructor */  
  22.                 Name = "Sammy Jenkins";  
  23.                 Salary = 10000;   
  24.             }  
  25.         }  
  26.     }  
  27. }  
In C# 6.0
  1. using static System.Console;  
  2.   
  3. namespace NewInCSharp  
  4. {  
  5.     class Program  
  6.     {  
  7.         static void Main(string[] args)  
  8.         {  
  9.             Employee employee = new Employee();  
  10.   
  11.             WriteLine("Name: " + employee.Name + "\nSalary: " + employee.Salary);  
  12.   
  13.             ReadKey();  
  14.         }  
  15.         public class Employee  
  16.         {  
  17.             /* Getter only property with inline initialization */  
  18.             public string Name { get; } = "Sammy Jenkins"  
  19.   
  20.             /* Property with inline initialization */  
  21.             public decimal Salary { getset; } = 10000;   
  22.         }  
  23.     }  
  24. }  
nameof expression

Next is the nameof expression. In enterprise level applications, lines of code run like a mad horse. So there is no means of avoiding exception handling where it is necessary. Showing a specific type name with an error message can be a quick way to find the code block where the exception just occurred. But we should also consider refactoring issues. We cannot just simply append a hard coded type name string with an error message and show it to the user because the type name can be changed anytime while refactoring but hard coded string won't change accordingly. So C# 6.0 introduced this concept of nameof expression. A simple example would be like the following:

Before C# 6
  1. using System;  
  2. using static System.Console;  
  3.   
  4. namespace NewInCSharp  
  5. {  
  6.     class Program  
  7.     {  
  8.         private static void Main(string[] args)  
  9.         {  
  10.             try  
  11.             {  
  12.                 CallSomething();  
  13.             }  
  14.             catch (Exception exception)  
  15.             {  
  16.                 WriteLine(exception.Message);  
  17.             }  
  18.   
  19.             ReadKey();  
  20.         }  
  21.   
  22.         private static void CallSomething()  
  23.         {  
  24.             int? x = null;  
  25.   
  26.             if (x == null)  
  27.             {  
  28.                 throw new Exception("x is null");  
  29.   
  30.                 /* x is the type name. What if someone changes the type name from x to i? The exception below would be inappropriate. */  
  31.             }  
  32.         }  
  33.     }  
  34. }  
  35. class Program  
  36. {  
  37.     private static void Main(string[] args)  
  38.     {  
  39.         try  
  40.         {  
  41.             CallSomething();  
  42.         }  
  43.         catch (Exception exception)  
  44.         {  
  45.             WriteLine(exception.Message);  
  46.         }  
  47.   
  48.         ReadKey();  
  49.     }  
  50.   
  51.     private static void CallSomething()  
  52.     {  
  53.         int? x = null;  
  54.   
  55.         if (x == null)  
  56.         {  
  57.   
  58.   
  59.             throw new Exception("x is null");  
  60.         }  
  61.     }  
  62. }  
In C# 6.0
  1. using System;  
  2. using static System.Console;  
  3.   
  4. namespace NewInCSharp  
  5. {  
  6.     class Program  
  7.     {  
  8.         private static void Main(string[] args)  
  9.         {  
  10.             try  
  11.             {  
  12.                 CallSomething();  
  13.             }  
  14.             catch (Exception exception)  
  15.             {  
  16.                 WriteLine(exception.Message);  
  17.             }  
  18.   
  19.             ReadKey();  
  20.         }  
  21.   
  22.         private static void CallSomething()  
  23.         {  
  24.             int? number = null;  
  25.   
  26.             if (number == null)  
  27.             {  
  28.                 throw new Exception(nameof(number) + " is null");  
  29.             }  
  30.         }  
  31.     }  
  32. }  
await in catch/finally block

I think many of you were waiting for this feature in C# where you can write asynchronous codes inside catch and finally block. Well now you can do that.
  1. using System;  
  2. using System.Net.Http;  
  3. using System.Threading.Tasks;  
  4. using static System.Console;  
  5.   
  6. namespace NewInCSharp  
  7. {  
  8.     class Program  
  9.     {  
  10.         private static void Main(string[] args)  
  11.         {  
  12.             Task.Factory.StartNew(() => GetWeather());  
  13.             ReadKey();  
  14.         }  
  15.   
  16.         private async static Task GetWeather()  
  17.         {  
  18.             HttpClient client = new HttpClient();  
  19.             try  
  20.             {  
  21.                 var result = await client.GetStringAsync("http://api.openweathermap.org/data/2.5/weather?q=Dhaka,bd");  
  22.                 WriteLine(result);  
  23.             }  
  24.             catch (Exception exception)  
  25.             {  
  26.                 try  
  27.                 {  
  28.                     /* If the first request throws an exception, this request will be executed. Both are asynchronous request to a weather service*/  
  29.   
  30.                     var result = await client.GetStringAsync("http://api.openweathermap.org/data/2.5/weather?q=NewYork,us");  
  31.   
  32.                     WriteLine(result);  
  33.                 }  
  34.                 catch (Exception)  
  35.                 {  
  36.                     throw;  
  37.                 }  
  38.             }  
  39.         }  
  40.     }  
  41. }  
null conditional operator & null propagation

Again we have this new notion of null conditional operator where you can remove declaring a conditional branch to check to see if an instance of an object is null or not with this new ?. ?? null conditional operator syntax. The ?. is used to check if a instance is null or not, if its not null then execute the code after ?. but if it is not then execute code after ??. Check out the example below,

Before C# 6.0
  1. using System;  
  2. using static System.Console;  
  3.   
  4. namespace NewInCSharp  
  5. {  
  6.     class Program  
  7.     {  
  8.         private static void Main(string[] args)  
  9.         {  
  10.             SuperHero hero = new SuperHero();  
  11.             if (hero.SuperPower == String.Empty)  
  12.             {  
  13.                 hero = null;  
  14.             }  
  15.   
  16.             /* old syntax of checkig if an instance is null or not */  
  17.             WriteLine(hero != null ? hero.SuperPower : "You aint a super hero.");  
  18.   
  19.             ReadLine();  
  20.         }  
  21.     }  
  22.   
  23.     public class SuperHero  
  24.     {  
  25.         public string SuperPower { getset; } = "";  
  26.     }  
  27. }  
In C# 6.0
  1. using System;  
  2. using static System.Console;  
  3.   
  4. namespace NewInCSharp  
  5. {  
  6.     class Program  
  7.     {  
  8.         private static void Main(string[] args)  
  9.         {  
  10.             SuperHero hero = new SuperHero();  
  11.             if (hero.SuperPower == String.Empty)  
  12.             {  
  13.                 hero = null;  
  14.             }  
  15.   
  16.             /* New null conditional operator */  
  17.             WriteLine(hero?.SuperPower ?? "You aint a super hero.");  
  18.   
  19.             ReadLine();  
  20.         }  
  21.     }  
  22.   
  23.     public class SuperHero  
  24.     {  
  25.         public string SuperPower { getset; } = "";  
  26.     }  
  27. }  
Again checking a list instance if it is null or not and then accessing its index is also somewhat similar.
  1. using System;  
  2. using System.Collections.Generic;  
  3. using static System.Console;  
  4.   
  5. namespace NewInCSharp  
  6. {  
  7.     class Program  
  8.     {  
  9.         private static void Main(string[] args)  
  10.         {  
  11.             List superHeroes = null;  
  12.             SuperHero hero = new SuperHero();  
  13.   
  14.             if (hero.SuperPower != String.Empty)  
  15.             {  
  16.                 superHeroes = new List();  
  17.                 superHeroes.Add(hero);  
  18.             }  
  19.   
  20.             WriteLine(superHeroes?[0].SuperPower ?? "There is no such thing as super heros.");  
  21.             ReadLine();  
  22.         }  
  23.     }  
  24.   
  25.     public class SuperHero  
  26.     {  
  27.         public string SuperPower { getset; } = "";  
  28.     }  
  29. }  
What if you want to invoke an event/delegate after checking if the handler function is null or not? Well the null checking syntax would be like in the example below. It is also known as null propagation.

Before C# 6.0
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.ComponentModel;  
  4. using static System.Console;  
  5.   
  6. namespace NewInCSharp  
  7. {  
  8.     class Program  
  9.     {  
  10.         private static void Main(string[] args)  
  11.         {  
  12.             Movie movie = new Movie();  
  13.             movie.Title = "The Shawshank Redemption";  
  14.             movie.Rating = 9.3;  
  15.             WriteLine("Title: "+ movie.Title + "\nRating: " + movie.Rating);  
  16.             ReadLine();  
  17.         }  
  18.     }  
  19.   
  20.     public class Movie : INotifyPropertyChanged  
  21.     {  
  22.         public string Title { getset; }  
  23.         public double Rating { getset; }  
  24.         public event PropertyChangedEventHandler PropertyChanged;  
  25.   
  26.         protected void OnPropertyChanged(string name)  
  27.         {  
  28.             PropertyChangedEventHandler handler = PropertyChanged;  
  29.   
  30.             /* Old systax of checking if a handler is null or not */  
  31.             if (handler != null)  
  32.             {  
  33.                 handler(thisnew PropertyChangedEventArgs(name));  
  34.             }  
  35.         }  
  36.     }  
  37. }  
In C# 6.0
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.ComponentModel;  
  4. using static System.Console;  
  5.   
  6. namespace NewInCSharp  
  7. {  
  8.     class Program  
  9.     {  
  10.         private static void Main(string[] args)  
  11.         {  
  12.             Movie movie = new Movie();  
  13.             movie.Title = "The Shawshank Redemption";  
  14.             movie.Rating = 9.3;  
  15.             WriteLine("Title: "+ movie.Title + "\nRating: " + movie.Rating);  
  16.             ReadLine();  
  17.         }  
  18.     }  
  19.   
  20.     public class Movie : INotifyPropertyChanged  
  21.     {  
  22.         public string Title { getset; }  
  23.         public double Rating { getset; }  
  24.         public event PropertyChangedEventHandler PropertyChanged;  
  25.   
  26.         protected void OnPropertyChanged(string name)  
  27.         {  
  28.             PropertyChangedEventHandler handler = PropertyChanged;  
  29.   
  30.             /* Null propagation syntax */  
  31.             handler?.Invoke(thisnew PropertyChangedEventArgs(name));  
  32.         }  
  33.     }  
  34. }  
Expression bodied function & property

You can now write functions and computed properties like lamda expressions to save extra headache of defining function and property statement block. Just use the lambda operator => and then start writing your code that goes into your function/property body. Here is a simple example,
  1. using static System.Console;  
  2.   
  3. namespace NewInCSharp  
  4. {  
  5.     internal class Program  
  6.     {  
  7.         private static void Main(string[] args)  
  8.         {  
  9.             double x = 1.618;  
  10.             double y = 3.142;  
  11.   
  12.             WriteLine(AddNumbers(x, y));  
  13.             ReadLine();  
  14.         }  
  15.   
  16.         /* Expression bodied function */  
  17.         private static double AddNumbers(double x, double y) => x + y;  
  18.     }  
  19. }  
For expression bodied property:
  1. using static System.Console;  
  2.   
  3. namespace NewInCSharp  
  4. {  
  5.     class Program  
  6.     {  
  7.         private static void Main(string[] args)  
  8.         {  
  9.             Person person = new Person();  
  10.             WriteLine("I'm " + person.FullName);  
  11.             ReadLine();  
  12.         }  
  13.   
  14.         public class Person  
  15.         {  
  16.             public string FirstName { get; } = "Fiyaz";  
  17.             public string LastName { get; } = "Hasan";  
  18.   
  19.             /* Expression bodied computed property */  
  20.             public string FullName => FirstName + " " + LastName;  
  21.         }  
  22.     }  
  23. }  
static using with Extension methods

This one is kind of related to the first one. Those of you who are wondering that if I import static types in my namespace how would I deal with the extension methods. Well extension methods are also static methods. It is true if you import a static type which have a extension method, you just cannot access the extension methods. It says, "The name [name of the function] does not exist in the current context". So what to do then? Well you can explicitly write the static type name like in C# 5 or previous versions or you can simply execute the function on one of its accepted types. Let me make it clear by an example,

Before C# 6
  1. using System;  
  2.   
  3. namespace NewInCSharp  
  4. {  
  5.     class Program  
  6.     {  
  7.         private static void Main(string[] args)  
  8.         {  
  9.             Shape shape = new Shape();  
  10.             ShapeUtility.GenerateRandomSides(shape);  
  11.             Console.WriteLine(ShapeUtility.IsPolygon(shape));  
  12.             Console.ReadLine();  
  13.         }  
  14.     }  
  15.     public class Shape  
  16.     {  
  17.         public int Sides { getset; }  
  18.     }  
  19.   
  20.     public static class ShapeUtility  
  21.     {  
  22.         public static bool IsPolygon(this Shape shape)  
  23.         {  
  24.             return shape.Sides >= 3;  
  25.         }  
  26.   
  27.         public static void GenerateRandomSides(Shape shape)  
  28.         {  
  29.             Random random = new Random();  
  30.             shape.Sides = random.Next(1, 6);  
  31.         }  
  32.     }  
  33. }  
In C# 6.0 importing static types and accessing extension methods of them like the code above will give you a error. The following code will generate the "The name 'IsPolygon' does not exist in the current context".
  1. using System;  
  2. using static System.Console;  
  3. using static NewInCSharp.ShapeUtility;  
  4.   
  5. namespace NewInCSharp  
  6. {  
  7.     class Program  
  8.     {  
  9.         private static void Main(string[] args)  
  10.         {  
  11.             Shape shape = new Shape();  
  12.             GenerateRandomSides(shape);  
  13.             WriteLine(IsPolygon(shape));  
  14.             ReadLine();  
  15.         }  
  16.     }  
  17.     public class Shape  
  18.     {  
  19.         public int Sides { getset; }  
  20.     }  
  21.   
  22.     public static class ShapeUtility  
  23.     {  
  24.         public static bool IsPolygon(this Shape shape)  
  25.         {  
  26.             return shape.Sides >= 3;  
  27.         }  
  28.   
  29.         public static void GenerateRandomSides(Shape shape)  
  30.         {  
  31.             Random random = new Random();  
  32.             shape.Sides = random.Next(1, 6);  
  33.         }  
  34.     }  
  35. }  
So to get over this issue you can simply modify you code like this,
  1. using System;  
  2. using static System.Console;  
  3. using static NewInCSharp.ShapeUtility;  
  4.   
  5. namespace NewInCSharp  
  6. {  
  7.     class Program  
  8.     {  
  9.         private static void Main(string[] args)  
  10.         {  
  11.             Shape shape = new Shape();  
  12.             GenerateRandomSides(shape);  
  13.   
  14.             /* You can write WriteLine(ShapeUtility.IsPolygon(shape));. But here I'm executing extension method on shape type, thats why they are called extension methods since there are just a extension of your type. duh! */  
  15.   
  16.             WriteLine(shape.IsPolygon());   
  17.             ReadLine();  
  18.         }  
  19.     }  
  20.     public class Shape  
  21.     {  
  22.         public int Sides { getset; }  
  23.     }  
  24.   
  25.     public static class ShapeUtility  
  26.     {  
  27.         public static bool IsPolygon(this Shape shape)  
  28.         {  
  29.             return shape.Sides >= 3;  
  30.         }  
  31.   
  32.         public static void GenerateRandomSides(Shape shape)  
  33.         {  
  34.             Random random = new Random();  
  35.             shape.Sides = random.Next(1, 6);  
  36.         }  
  37.     }  
  38. }  
There is one more feature that is 'Exception Filtering'. I wrote a separate post for that. Check it out here, Exception filtering in C# 6.0.

So, these are some new feature of C# 6.0 explained with some simple example. To know more on what's coming next, be sure to keep your eye on this git repo documentation,

New Language Features in C# 6

Hope you enjoyed the post. Share it if you like.


Recommended Free Ebook
Similar Articles