New C# 6.0 comes with no big concepts, but it is packed with very useful, highly effective functionalities which all developers should use in the daily coding life. These functionalities can help you to clean up your code.
Getter-only auto-properties
example: public int X {get;}
C# 6.0 allows us to have a getter only auto property. This is good for the immutable elements. In the background, what C# does is to store the value of the auto property in a read-only variable.
Initialize value for auto property
example:
public class Point()
{
public Point(int x, int y) {X=x; Y=y;}
}
In C# 6.0, we could initialize the value of the auto property when we declare the property. The auto property can be a getter auto property or normal auto property. With this new functionality, we could initialize the value of the property in constructor of the class.
Using Static Members
example: using static System.Math;
With C# 6.0, we could do using on the static classes so that we could use the static methods directly in our code rather than mentioning the static class name over and over again in our code.
String Interpolation
example: $"({X}, {Y})";
We could use the new $ for string interpolation rather than using the long syntax of String.format(). This new syntax makes the code much cleaner and shorter.
Expression-bodied properties and methods
example:
public override string ToString() => $"({X}, {Y})";
public double Dist => Sqrt(X*X + Y*Y);
C# 6.0 makes the syntax for simple functions and getter auto properties to a simple one liner. This is taken from the lambda expressions. Now the functions and getter properties can be defined just like a lambda expression in your code. This makes the code nice and clean.
Index Initializers
In C# .0, we will be able to use initializers that use indexes.
example:
var numbers = new Dictionary<int, string>{ [7] = "AB", [9] = "NO", [13] = "YZ"};
In C# .0, we will be able to use initializers that use indexes.
example:
var numbers = new Dictionary<int, string>{ [7] = "AB", [9] = "NO", [13] = "YZ"};
Exception Filters
In C# 6.0, we could have exception filters. If the evaluation of the expression in the parentheses after the "When" in the "Catch" block evaluates to true, the exception is caught. Or else, the "Catch" block is ignored.
example:
1:
try
{
...
}
catch (Exception ex) when (SomeFilter(ex))
{
...
}
2:
try
{
//...
}
catch (SqlException ex) when (ex.Number == 2)
{
// ...
}
catch (SqlException ex)
{
// ...
}
Note that, the filters are executed in the context of the "throw" and not in the context of the "catch" because the stack has not been unwound yet. Exception filters are preferable to catching and re-throwing because they leave the stack unharmed.
Await in catch and finally blocks
We could use the Await in catch and finally blocks in C# 6.0.
example :
Resource res = null;
try
{
res = await Resource.OpenAsync(…);
…
}
catch(ResourceException e)
{
await Resource.LogAsync(res, e);
}
finally
{
if (res != null) await res.CloseAsync();
}
try
{
res = await Resource.OpenAsync(…);
…
}
catch(ResourceException e)
{
await Resource.LogAsync(res, e);
}
finally
{
if (res != null) await res.CloseAsync();
}
nameof expressions
Using string literals for naming the methods is simple for the purpose of logging. But this is error prone as some times refactoring may leave it stale. "nameof" expression is a fancy kind of literal where the compiler checks that you are having something of the given name, and Visual studio knows that is refers to, so that the navigating and refactoring will work.
example :
if (x == null) throw new ArgumentNullException(nameof(x));
Null-conditional operators
Null conditional operator makes the null checking very simple and thus eliminates complex null checking conditional codes. It lets you access members and elements only when receiver is not null, providing a null otherwise.
example :
int? length = customers?.Length; // null if customers is null
Customer first = customers?[0]; // null if customers is null
int length = customers?.Length ?? 0; // 0 if customers is null
int? first = customers?[0].Orders.Count();
None of the member accesses, element accesses and invocations immediately following the ? are executed unless the object in question has a non-null value.
Conclusion
C# 6.0 comes with no ground breaking enhancements, but it is filled with very essential enhancements which makes code cleaner and simple and thus making developer's life easier.