Monday, 30 November 2015

Useful Features of C# 6

nameof Expression

So many times, we have to use magic strings within our code which essentially map to program elements. For such cases, nameof expression can be pretty useful to access the name of program element.

For example,


public ActionResult Details(int? id)



{

 /* some code*/



 Employee employee = db.Employees.Find(id);



 System.Diagnostics.Trace.WriteLine(String.Format("The value 



   of variable {0} = {1} is not valid", 



   nameof(id), id));



 /* some code*/



return View(employee);



}
So by using nameof expression, we don't have to hard code the string id in our trace statement. We can simply use nameof(id). So in future, if we decide to change the name of this variable to something else (right click, Refactor -> Rename), we don't have to worry about updating all our trace statements throughout our code. The nameof expression will use the variable name by itself. This will certainly save us time during refactoring :)

Auto Property Initializers

 Earlier, in order to make a field read-only and set some value to the field, we had to use explicit implementation. We used to set the value of read-only defined backing field and initialize it from within the constructor. Now with C# 6.0 we can assign the value of the property from within their declaration. For example,


public class Employee



    {



        public int EmployeeId { get; set; }







        public string Department { get; } = "Development";







    }



As only get method is exposed, the field becomes read-only. As a result, the underlying backing field automatically becomes read-only. So this makes it more convenient to set the value using auto property initializers.

Null Conditional Operator

This is my favorite one and I think I will be using this the most. So many times, we have lots of null checks throughout our code to avoid null reference exceptions. For example,


            int? myInteger;



            if (myInteger == null)



                return null;



            else



                return myInteger.ToString();





These null checks just pollute our code base and make it look bulky. Now, with the new null conditional operator, we can simply do this:


return myInteger?.ToString();

This will essentially do the same thing as the code above but now it's simply written in 1 line instead of 4 lines. So if myInteger is null, it will return null without throwing any null reference exception. How cool is that?

String Interpolation

I prefer using String.Format for string formatting instead of combining multiple strings using + operator. However, with String.Format() using indexed formatters was somewhat of a pain as my eyes had to go back and forth to see what's the element at zeroth index and first index and so on. As I showed in an example above, String.Format looks like this:


String.Format("The value of variable {0} = {1} is not valid",

 nameof(id), id)

With the new string interpolation feature in C# 6, we can create string expressions that look like a template string containing expressions. The expressions are replaced by their ToString() representations of the expression's result. By using the $ escape character we can simply embed the string name inside curly braces.


System.Diagnostics.Trace.WriteLine($"The value of variable 

{nameof(id)} = {id} is not valid");
In my opinion, it's easier to read and follow an interpolated string.

Exception Filters

With this new feature, you can specify condition along with the catch block. So the exception will be caught only when the condition is met, otherwise it will be skipped.
For example,


string ErrorCode = "1234";



 try



 {



     throw new Exception("User Error");



 }



 catch (Exception ex) when (ErrorCode == "5678")



 {



     System.Diagnostics.Trace.WriteLine("Error 5678");



 }



 catch (Exception ex) when (ErrorCode == "1234")



 {



     System.Diagnostics.Trace.WriteLine("Error 1234");



 }



catch (Exception ex)



 {



     System.Diagnostics.Trace.WriteLine("Error Unknown");



}



 finally



 {



     System.Diagnostics.Trace.WriteLine("Finally Block");



}

So as you can see, there are multiple catch blocks here. Since Error Code = 1234 is true, only that catch block gets executed. And finally block gets executed as expected.