Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

What is Cool about C# 6.0?

0.00/5 (No votes)
25 Feb 2015 1  
Features included in C# 6.0 that can help us to have better and readable code

Introduction

C# as a language has been there since 12 years. It came along with .NET Framework. And year after year, various versions of C# were released. Let’s have a glance at how C# was available through the years.

Looking at the history, C# really helped us to make our code more readable & easy to achieve our work. But today, in this article, I would like to talk about the upcoming version of C# language, i.e., – C# 6.0. Although you can find a lot of articles related to C# 6.0 features, I will try to explain the problem today and how this new version will help us to solve it efficiently.

C# 6.0 hasn’t added any huge features in this version, but instead they tried to add small features which will help us to keep our code clean.

Features

1) Null Check Operator

Every time we try to access any methods or property of null object, we usually get a worst & common exception, i.e., – NullReferenceException.

The above figure explains that I tried to use Split() to null string. Now how would you handle this exception?

string strName = null;
string strFirstName = null, strLastName = null;
if (strName != null)
{
    string[] splitName = strName.Split();
    strFirstName = splitName[0];
    strLastName = splitName.Length > 1 ? splitName[1] : null;
}
Console.WriteLine("Splited Data FrstName :{0}  LastName :{1}", strFirstName, strLastName);

I tried to first check whether strName is null or not, then after splitting checked for array length > 1 or not before assigning LastName.

But now, in C# 6.0, this job is done in a much simpler way using ?. operator. This is called as Null Check Operator or Null propagation operator.

string strname = null;
string[] splitname1 = strName?.Split();
Console.WriteLine("Splited Data Frstname :{0}  Lastname :{1}", splitname1
?[0], splitname1?[1]);

Check the above code snippet.

Null Check operator (?.) helps:

  • Return null if the operand is null. Example - strName?.Split()
  • Return null if indexed object is null. Example - splitName?[0]

Isn’t it cool? Now the same is also applicable for nullable type member.

int? result = strName?.Length; 

From the above code snippet, if strName is null, so Length property as it is a value type will get converted to nullable automatically.

2) Auto Property Initializer

Usually, when we declare any property, how did we declare it?

Old method:

    private readonly Guid _idOld = Guid.NewGuid();//Backing Field
    public Guid Id
    {
        get { return _idOld; }
    }

Right, then in C# 4.0, we got automatic implement property, where we stopped writing implementation of getter & setter.

    public Customer()
    {
        NewId = Guid.NewGuid();
    }
	public Guid NewId
    {
        get; protected set;
    }

Now, you may know that in this way of writing where I want to have only getter accessor for property, we have to have the protected setter accessor as well just to set the initial backing field at constructor. The reason was for mutable datatype property, we cannot declare variable and leave it without assigning default value, we have to set it, due to which immutable datatype property was also suffering from this forced set accessor.

In C# 6.0, that problem is permanently removed.

    public Guid Id { get; } 

    public int Number { get; }

Also initialization of property need not be done in constructor, you can do it at the same line of property declaration.

//Auto property initialization
public Guid Id { get; } = Guid.NewGuid();

3) Expression Bodied Function and Members

Whenever we create any method, which consists of single line statement, we normally write it down as shown below:

    public string GetName0(string fullname)
    {
        return fullname;
    }

    public void Calculate0(int x, int y)
    {
        Console.WriteLine("Total:" + (x + y));
    }

One method GetName0() return a value & Calculate0() returns void.

If you see, it takes around 3 lines of code just for a single one liner statement body.

Now C# 6.0 comes with the expression bodied functions which use a lambda expression to define the body of a method.

    public string GetNameN(string fullname) => fullname;

    public void CalculateN(int x, int y) => Console.WriteLine("Total:" + (x + y));

4) Using Static

We use various .NET or user defined classes by importing namespaces in our code.

//Using directive
using System.IO;
using System;

namespace cSharp6
{
    public class UsingStatic
    {
        public void ReadFile()
        {
            string[] filecontent = File.ReadAllLines("c:/test/sample.txt");
            Console.WriteLine("Reading file:samle.txt");
            Console.WriteLine("--------------------------------------");
            foreach (string s in filecontent)
            {
                Console.WriteLine(s);
            }
        }

If you see the above sample code, I am trying to read the sample.txt and print it on console.

For reading the file, I made use of System.IO namespace.

I hope you all know that File is a static class that falls under System.IO namespace.

In C# 6.0, we can keep our code more clean as it now allows you to import Static classes in using directive.

using System.Console;
using System.IO.File;
using System;

namespace cSharp6
{
    public class UsingStatic
    {
        public void ReadFile()
        {
            string[] filecontent = ReadAllLines("c:/test/sample.txt");
            WriteLine("Reading file:samle.txt");
            WriteLine("--------------------------------------");
            foreach (string s in filecontent)
            {
                WriteLine(s);
            }
        }

Note: Let's say you have a custom method with name WriteLine() already in your class. In that case, no ambiguity error will occur and preference will be given to internal class method and not Static class method.

5) Dictionary Initializer

When you declare any dictionary, how do we normally create it?

Note: Dictionary class was brought in C# 3.0.

public Dictionary<string, Customer> clist = new Dictionary<string, Customer>();

The above dictionary is holding Customer object.

Same dictionary when created with object initializer then?

    //Dictionary Initializer
    public Dictionary<string, Customer> clist = new Dictionary<string, Customer>()
    {
        {"a", new Customer() { CustomerName = "Ron" }},
        {"b", new Customer() { CustomerName = "Robert" }}
    };

If you see, it sometimes gets very difficult to manage the braces, we sometimes get confused with the closing curly braces.

So to make our work easier and development faster, C# 6.0 came up with a syntax as shown below:

    public Dictionary<string, Customer> clist = new Dictionary<string, Customer>()
    {
        ["a"] = new Customer() { CustomerName = "Ron" },
        ["b"] = new Customer() { CustomerName = "Robert" }
    };

Now, you can set the key of dictionary by assigning the value. Is it cool?

I really liked this code stuff as many times our dictionary value could be a complex class.

6) String Interpolation

When we print something, let's say on browser, messagebox, console, etc., we either write:

Console.WriteLine("My fav football player is " + firstName + " " + lastName);

Or we use string.Format() method with placeholder:

Console.WriteLine(string.Format("My fav football player is {0} {1}", firstName, lastName));
//Values will get replaced sequentially

Think of a situation if the string you are printing is huge with many placeholder’s values, it becomes difficult to manage and count the placeholder values, else it will give an error.

What if C# 6.0 gives you a better way to represent the string? This is what is called as string interpolation.

Previous CTP version of VS2015 was having syntax as shown below

 Console.WriteLine("My fav football player is \{firstName} \{lastName}");

You can use \{} character and replace the variables within these curly brackets.

Now in the latest CTP version, i.e., CTP 6, the syntax has been changed a bit. Now they used $ and made it much simpler.

Console.WriteLine($"{firstname} {lastname}");

Now, you don’t need to remember how many placeholders are defined and how many variables are declared. (Note: This situation mainly comes when string is a huge string.)

You may be thinking what in case I want {firstname} as a part of string and not placeholder. In that case, use \. It will consider it as escape character. i.e. \{firstname}.

Note: This syntax was already present in Python language, now adopted by Microsoft for C#.

7) Exception Filter

Catching an exception is the most required part in our day to day coding. When we want to handle any exception, we normally use try catch block.

My condition here is I want to handle only InvalidOperationException, check what I did in the code below:

    public void CalculateO(int x, int y)
    {
        try
        {
            int index = 10;
            int j = (x*index) / y;
        }
        catch (Exception e)
        {
           if (e.Message.Contains("InvalidOperationException"))
                Console.WriteLine("Mail error 2:" + e.Message);
            throw;
        }
    }

I added a condition in catch block for error message containing ‘InvalidOperationException’.

Now check the same Exception handling provided in C# 6.0.

    public void CalculateN(int x, int y)
    {
        try
        {
            int index = 10;
            int j = (x*index) / y;
        }
        catch (InvalidOperationException e)if(e.Message.Contains("unknown error"))
        {
            Console.WriteLine("Mail error 1:" + e.Message);
        }          
    }

The above code snippet shows the catch along with contextual if statement.

Reading many articles on C# 6.0 and from audience comments, you may feel both are almost the same and of no use, in fact I may have to write multiple catch blocks in C# 6.0 syntax if more conditions need to be checked which is very simple in the previous code.

Then, why C# got this code?

An answer is there is a huge fundamental difference between both the code snippets above.

In the 1st way, I am first catching the block and then checking the condition, i.e., – Exception is caught already In the 2nd way, I am checking the condition and then moving to catch block, i.e.,- Exception is caught on satisfying the condition

In the first case, if you want the exception other than your condition, then you will rethrow the exception and your exception will be bubbled up. But at the same time, you will lose your critical information because of crash dumps like from which line the exception was rethrown & what were the values, let's say index was holding as shown in the below figure.

Check what advantage we have in the new syntax. You are getting the unhandled exception there itself.

In the 1st case catch block, the local variable is not on the top stack frame. This fairly corresponds to what you see in the crash dumps.

Notice in the 2nd case, you can easily investigate the error location and it helps you better to understand it.

8) Async Await with Await in Catch Block

We know that async await keywords were introduced in C# 5.0. This are mainly meant for asynchronous calls. Let’s consider a sample example wherein I am having a method which is taking time for processing.

    public async void AsyncCall()
    {
        Console.WriteLine("Called..");
        Task<string> theTask = ProcessData();
        try
        {
            string result = await theTask;
            Console.WriteLine("Result: " + result);
        }
        catch (Exception ex)
        {        
            Console.WriteLine("Result: " + ex.Message);
        }
    }
    private async Task<string> ProcessData()
    {
        //Processing data;
        await Task.Delay(1000);
        return "Processed all records";
   }

As shown in the code above, ProcessData() method is processing data for 10 minutes asynchronously, and I get an error, I will catch that Exception in catch block.

Imagine that I want to log the exception in catch block and that too takes some 20 minutes.

Don’t you think it should also be called using await keyword for asynchronous call. This was not possible in C# 5.0. There is no reason for it.

But with C# 6.0, using await in catch block has become possible. See the updated code below:

    public async void AsyncCall()
    {
        Console.WriteLine("Called..");
        Task<string> theTask = ProcessData();
        try
        {
            string result = await theTask;
            Console.WriteLine("Result: " + result);
        }
        catch (Exception ex)
        {        
            Console.WriteLine("Result: " + await LogError(ex));
        }
    }
    private async Task<string> ProcessData()
    {
        //Processing data;
        await Task.Delay(1000);
        return "Processed all records";
   }
   public async Task<string> LogError(Exception ee)
   {  
        await Task.Delay(2000);
        Console.WriteLine("Logging....");
        return ee.Message;
   }

Some of the features were decided to be a part of C# 6.0, but later were removed from this version. They are:

  • Primary Constructor
  • Prams & IEnumerable
  • Declaration Expression
  • Literals & separators

Conclusion

Here, I end up my features of C# 6.0. Some are really cool and will definitely help us to keep our code clean and easily readable.

Just to make you aware again that C# 6.0 is not yet released. It is still under CTP version of Visual Studio 2015. But soon, it is going to get released and will be available with us.

Please do share your comments, whether good or bad. Your feedback will definitely motivate me to write better.

The Visual Studio 2015 CTP version can be download from the below link:

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here