1 Auto Property Initializer
Auto property is not the new feature but this was there from C sharp 3.0 onwards.
Drawbacks
We cannot initialize the backing field during object initialization, But you can initialize explicitly in constructors.
Example:
Output:
In the above example you can see
FirstName and LastName were Auto - Implemented properties, and the values initialized during constructor call.
But with C sharp 6.0
public class AutoPropertyInitializer
{
public string FirstName { get; set; } = "Uday";
public string LastName { get; } = "Kumar";
//public string FullName { get; } = this.FirstName + this.LastName;
public string FullName { get; }
public AutoPropertyInitializer()
{
this.FullName = this.FirstName + " " + this.LastName;
}
}
The FirstName and LastName were initialized directly after the declaration. You can notice the LastName were made
readonly
by not mentioning the setter. The backing field produced for a readonly property is also a readonly variable.
The FullName though it is initialized inside constructor as the object
initialization works before the constructor call, and hence
initialization cannot evaluate "this".
2 Static Class Uses:
If we want to print something we use Console.WriteLine. Why can I use only
WriteLine ? instead of
Console.WriteLine.
Static class uses does the same thing. Static class uses also recognize
extension
methods, hence if say a static class defines extension methods, if you
add it, it will automatically recognize the extension methods as well.
But with C sharp 6.0
using
static System.Console;
using
static System.Linq.Enumerable;
public
class
UseStatic
{
public
void
CallMe()
{
WriteLine("Hi"); //Console.WriteLine
var range = Range(10,
10); //From the namespace Linq.Enumerable
var
check = range.Where(e => e > 13);
// Static extension method can
// only be called with fulll representation
}
}
In
the above code the WriteLine is automatically detected as we added the
head using static statement. The static uses automatically recognized
the extension methods
as well.
If you look at the internals of the static uses, the compiler rewrites the static type calls on every occurrences of its
method call.
In
the actual IL, you can see, the WriteLine is padded with its
appropriate type Console and Range is also associated with Enumerable.
The re-writing
is done by the compiler.
3 Null conditional operators
For developers Enemy exception are NullReferenceException or "Object reference not set to instance of an object"
is one of the most common exception. For this developer need to check
the null value before calling any member functions. Null for
compiler is unknown, and hence if you call a method on null, it will
point nowhere and hence throws
NullReferenceException and exists the stack.
Microsoft already introducted
Null coalesce operator (??) or Conditional operators.
string name = (student == null? null : student.name);
In the first statement the student is checked with null and when it has student, it will only then evaluate the name.
string postalcode = (student == null? null : (student.address == null ? null : student.address.postalcode))
On the second statement, the student object is checked with null, then its address and then finally the postalcode is evaluated.
But with C sharp 6.0
string name = student?.name;
string postalcode = student?.address?. postalcode;
Here code is reduced but the actual logic remains the same.
The ? mark is used for null conditioning.
Null conditional operators does not exists as well, it is the same representation as that of the previous conditional operators.
Note: You can see the null conditional operators are replaced by the compiler with normal conditional statements.
4 Exception Filters
In C# the exception block contains try/catch/finally with multiple catch blocks supported.
Based on type of the exception that has been encountered during
runtime, the runtime chooses the appropriate catch block to execute.
But with C sharp 6.0
Exception filters it allows you to filter out the catch blocks to ensure which catch block can handle the exception. With
exception filters in place, there could be multiple catch blocks with same type where the type determines which filter it will call first.
Let us take a look at the code :
public class ExceptionFilters
{
public static bool LogException(Exception ex)
{
//Log
return false;
}
public static bool LogAgainException(Exception ex)
{
//Log
return true;
}
public void CallMe()
{
try
{
throw new ArgumentException("Exception");
}
catch (Exception ex) when (LogException(ex))
{
//Keep exception stack intact
}
catch(Exception ex) when (LogAgainException(ex))
{
// Calling the catch
}
}
}
Here the ArgumentException is thrown when CallMe is invoked. So the
execution is like, it will call LogException method, executes the code
and see whether the return statement is
true or false. If it is true, it executes the catch block and exit, or otherwise it move and call
LogAgainException method.
The exception filter expects a boolean value, hence the call to LogException should be a method returning bool.
5 nameof Operator
But with C sharp 6.0
Here the compiler determines the name of a Property, Function or an
Extension method and writes it directly in compiled output. For
instance,
string name1 = nameof(this.MyProp); // evaluates MyProp
string name2 = nameof(DateTime.Now);//evaluates Now
string name3 = nameof(Console.WriteLine); //evaluates WriteLine
string name4 = nameof(new List<string>().FirstOrDefault); // Evaluates FirstOrDefault
string name5 = nameof(name4); //Evaluates name4
The nameof operator works on any type where the type has a name. In case you specify a variable, the nameof operator will
evaluate to the name of the variable.
6 Dictionary initializers
var dict = new Dictionary<int,string>();
dict.Add(0, "Uday");
dict.Add(1, "Kumar");
//Access
var first = dict[0];
var second = dict[1];
In C# 6.0, you can define dictionary using the following syntax :
var dict = new Dictionary<int,string>
{
[10] = "Uday",
[20] = "Kumar"
};
//Access
var first = dict[10];
var second = dict[20];
Or even if the key is declared as string, you can also use like:
var dict = new Dictionary<string,string>
{
["first"] = "uday",
["second"] = "Kumar"
};
//Access
var first = dict["first"];
var second = dict["second"];
This way it is very easier to declare and use dictionaries. The last two syntaxes were introduced in C# 6.0.