Wednesday, May 28, 2014

Language Features in Up Coming C# 6.0 (Build 2014)

I am so excited to write this post in which I am going to explain the upcoming language features of  C# 6.0 which was announced in Microsoft Build 2014 Conference last month. To give you a surprise, to try these language features, you don’t have to wait until C# 6 is officially released. Once you download the Roslyn Preview and install it in your machine, you are ready to write C# 6.0 code.

If you haven’t heard about the C# 6.0 new language features already, I am sure you must be feeling excited to see those. So let’s dive in.

1. Using static

This feature allows specifying a type in a using clause, making all the accessible static members of the type available without qualification in subsequent code:
using System.Console; 

class Program
{
    static void Main(string[] args)
    {
        WriteLine("Hello C# 6.0");
    }
}
While this making our code shorter, it increases the risk of ambiguity. So you should be using this carefully.

2. Initializers for auto-properties

You can now add an initializer to an auto-property, just as you can to a field.
public class Employee
{
   public string FirstName { get; set; } = "Jaliya";
   public string LastName { get; set; } = "Udagedara";
}
The initializer directly initializes the backing field; it doesn’t work through the setter of the auto-property. So it now makes sense to have auto-properties without setters.
public class Employee
{
    public string FirstName { get; } = "Jaliya";
    public string LastName { get; } = "Udagedara";
}
But now there is another problem. Getter-only auto-properties would seem kind of useless if they couldn’t somehow acquire values passed in to constructors of the object. For this reason, now comes the concept of Primary Constructors.

3. Primary Constructor

Primary constructors allow constructor parameters to be declared directly on the class or struct, without an explicit constructor declaration in the body of the type declaration. These parameters are in scope as simple names for initialization throughout the whole class declaration.
3.1. Parameters on classes and structs
Here’s an example of a class with a primary constructor.
public class Employee(string firstName, string lastName)
{
    public string FirstName { get; set; } = firstName;
    public string LastName { get; } = lastName;
}
To achieve the same without primary constructors, we would have to write the code in the following way.
public class Employee
{
    private string firstName;
    public string FirstName
    {
        get
        {
            return firstName;
        }
    }

    private string lastName;
    public string LastName
    {
        get
        {
            return lastName;
        }
    }
 
    public Employee(string firstName, string lastName)
    {
        this.firstName = firstName;
        this.lastName = lastName;
    }
}
Now you can see with the introduction of primary constructors, we don’t have declare primary variables and write all those lines of code.
3.2. Field Parameters
By default, a Primary Constructor parameters are only around at initialization time. Function members such as properties and methods cannot refer to it, because by the time they are called, the object has been constructed and the parameter is gone.

For an example, consider the following code.
public class Employee(string firstName, string lastName, DateTime birthday)
{
    public string FirstName { get; } = firstName;
    public string LastName { get; } = lastName;
    public int Age
    {
        get
        {
            return (DateTime.Now.Year - birthday.Year);
        } 
    }
}
Here I am getting the error, “Parameters of a primary constructor can only be accessed in instance variable initializers and arguments to the base constructor.”. And for that you can declare private variable and initialize it with the parameter.
public class Employee(string firstName, string lastName, DateTime birthday)
{
   public string FirstName { get; } = firstName;
   public string LastName { get; } = lastName;
 
   private DateTime _birthday = birthday;
   public int Age
   {
       get
       {
           return (DateTime.Now.Year - _birthday.Year);
       }
   }
}
Unfortunately the private field wouldn’t be able to use the same name as the parameter, and needs some other name.

And for that C# 6 introduces, Field Parameters.
public class Employee(string firstName, string lastName, private DateTime birthday)
{
    public string FirstName { get; } = firstName;
    public string LastName { get; } = lastName;
    public int Age
    {
        get
        {
            return (DateTime.Now.Year - birthday.Year);
        }
    }
}

4. Declaration Expressions

I would say, this is one of my favorite feature in the up coming C# 6.0. Consider the following example.
int i;
if (Int32.TryParse("10", out i))
{
    Console.WriteLine(i);
}
Only for the out parameter, we had to declare a variable in a separate line. But not any more.
if (Int32.TryParse("10", out int i))
{
    Console.WriteLine(i);
}
And also, we don’t have to specifically say it’s an int. We can use var and compiler will understand and will be treated var as an int here.
if (Int32.TryParse("10", out var i))
{
    Console.WriteLine(i);
}

5. Indexed members and element initializers

Let’s take the following Dictionary collection initializer written using C# 5.0.
Dictionary<string, string> myDictionary = new Dictionary<string, string>()
{
  {"a", "Apple"},
  {"o", "Orange"},
};
Let’s say I want to access an item in the dictionary, this is how I would do it.
Console.WriteLine(myDictionary["a"]);
C# 6.0 has this new syntax to initialize objects allowing you to set values to keys through any indexer that the new object has.
Dictionary<string, string> myDictionary = new Dictionary<string, string>()
{
   ["a"] = "Apple",
   ["o"] = "Orange",
};
Not only that, there is this new syntax for “indexed members”, which let you pretend that a literal string key is a sort of member.
Dictionary<string, string> myDictionary = new Dictionary<string, string>()
{
    $a = "Apple",
    $o = "Orange",
};
You can access the elements using the same syntax.
Console.WriteLine(myDictionary.$a);

6. Await in catch and finally blocks

In C# 5.0 the await keyword cannot be used in catch and finally blocks. In C# 6.0, you can.
Resource res = null;

try
{
    res = await Resource.OpenAsync(…);       // You could do this.
}
catch (ResourceException e)
{
    await Resource.LogAsync(res, e);         // Now you can do this …
}
finally
{
    if (res != null) await res.CloseAsync(); // … and this.
}

7. Binary literals and digit separators

Binary literals will be allowed in C# 6.0.
var bits = 0b00101110;
For long literals (and these new binary ones can easily get long!) being able to specify digits in groups also seems useful. C# will allow an underscore ‘_’ in literals to separate such groups:
var bits = 0b0010_1110;
var hex = 0x00_2E;
var dec = 1_234_567_890;
You can put as many as you want, wherever you want, except at the front.

8. Exception filters

VB has them. F# has them. Now C# has them too. This is what they look like:
try
{ … }
catch (MyException e) if (myfilter(e))
{
}
If the parenthesized expression evaluates to true, the catch block is run, otherwise the exception keeps going. Exception filters are preferable to catching and re throwing because they leave the stack unharmed. If the exception later causes the stack to be dumped, you can see where it originally came from, rather than just the last place it was re thrown.

So that's it. Hope you all find this these new language features interesting. If you are, please leave your feedback to Microsoft.

Happy Coding.

Regards,
Jaliya

No comments:

Post a Comment