So,Let's start with describing the features one by one in details.
1.Index Initializers
This features was although introduced in C# 3.0 and C# 6.0 provides just more concise syntax over that.
public class Class { //C# 3.0 Dictionary<int, string> rollNumbers = new Dictionary<int, string> { { 1, "Abhishek" }, { 2, "Rahul" }, { 3, "Divya" } }; //C# 6.0 Dictionary<int, string> rollNumbersNew = new Dictionary<int, string> { [1] = "Abhishek" , [2] = "Rahul" , [3] = "Divya" }; }
2. Property Initializers
Let’s go in flashback and try to understand how properties evolved in .Net.
Properties are wrapper over fields which controls the way our fields should be accessed and modified.
A typical field:
private int i = 0;By default variable in a class are private which means they cannot be accessed outside the classes and are only accessible via member functions.
Making the variable public will mean anybody who has access to class object can modify the variable, which is not a secure way of dealing with class data.
Solution is properties:
A typical .Net 1.1 property
private int _i = 0; public int I { get { return _i; } set { _i = value; } }or we can use access modifiers with properties like:-
public int I { get { return _i; } protected set { _i = value; } }Above code means property is available via class objects but only child classes can set.
Come C# 3.0 And Automatic Properties:
C# 3.0 bring about the concept of automatic properties which removed the reliance on creating a field to be encapsulated by a property
public int I { get; set; }Still the gap was the properties can’t have a default value other than default value of type provided by the framework i.e. if you want to initialize property “I” declared above with value 5, we need to do that in constructor e.g.
public int I { get; set; } public A() { I = 5; }C# 6.0 – Automatic Property Initializers:
C# 6.0 removed this reliance of setting default properties in constructor by introducing Property Initializer, which is a concise way of providing default values as
class A { //Automatic Initialization of a read-write property public int I { get; set; } = 5; //Automatic Initialization of a read-only property public string FirstName { get; } = "Abhishek"; public A() { // I =5; //No longer needed now } }3. Initialize ReadOnly property from constructors
another feature is deferring the initialization of read-only property from constructor. This feature is available in most recent version of CTP
public class Person { public string FirstName { get; } public string LastName { get; } public Person(string firstName , string lastName) { FirstName = firstName; LastName = LastName; } }
4. Methods with Expression Body
Since its release, C# has travelled a long journey from being a imperative language to a declarative one. With this journey the way we use to write methods have also changed a lot. Lets try to understand the journey of a method from C# 1.0 to 6.0
This is how we use to write methods in C# 1.0 .These were called named methods.Also you can see how a delegate is using a named method to print a value to console.
class CSharp1 { public delegate void MyDelegate(string name); public void Hello() { Console.WriteLine("Hello"); //A delegate using a named method MyDelegate mydelegate = new MyDelegate(Print); mydelegate2("Abhishek"); } ////// Named Method /// /// private void Print(string name) { Console.WriteLine(name); } }
C# 2.0 Introduced Partial Methods as well as anonymous methods using delegate’s syntax
Partial Methods
partial class CSharp2 { partial void Hello(); } partial class CSharp2 { partial void Hello() { Console.WriteLine("Hello"); } }
Advantages:
- Allow developer working on same module to share contracts.
- Partial methods are simply ignored by compiler if no concrete definitions are present, giving them a great place in template driven programming
Limitations:
- Can only be private and void.
Anonymous methods:
Till C# 2.0 we could only create named methods. While using delegates sometimes we require methods having just one line of code as shown in example above. No matter how short a method is, we still need to create that as a named method. Named methods are good if we are going to call them from multiple places but if we just need to call them from a delegate i.e. a single place, it’s kind of an overhead to create a named method. C# 2.0 introduces the concept of anonymous methods to be used in delegates.
public class CSharp2O { public delegate void MyDelegate(string name); public void Hello() { Console.WriteLine("Hello"); //A delegate using a named method MyDelegate mydelegate = new MyDelegate(Print); mydelegate("Abhishek"); //Delegate using anonymous method to achieve same functionality MyDelegate mydelegate2 = new MyDelegate(delegate(string name) { Console.WriteLine(name); }); } ////// Named Method /// /// private void Print(string name) { Console.WriteLine(name); } }
C# 2.0 also introduced 2 new delegates which changed the way we write methods.
public class CSharp2O { public delegate void MyDelegate(string name); public Predicate<int> IsEven = delegate(int i) { return i%2==0; }; public Action<string> PrintIt = delegate(string s) { Console.WriteLine(s); }; }
C# 3.0 went step further ahead and introduced Lambda expressions. Let’s try to understand the journey of Lambda expression syntax using some examples:
public class CSharp3O { public delegate void MyDelegate(string name); public void Hello() { Console.WriteLine("Hello"); //A delegate using a named method MyDelegate mydelegate = new MyDelegate(Print); //Delegate using anonymous method to achieve same functionality MyDelegate mydelegate2 = new MyDelegate(delegate (string name) { Console.WriteLine(name); }); //Lambda expression Step By Step.. Step 1 //As you see just removed delegate keyword from above and placed => symbol after parameters MyDelegate mydelegate3 = new MyDelegate((string name)=> { Console.WriteLine(name); }); //Lambda expression Step By Step.. Step 2 //Since type is inferred in delegates. We don't require type in parameter.Let's remove MyDelegate mydelegate4 = new MyDelegate((name) => { Console.WriteLine(name); }); //Lambda expression Step By Step.. Step 3 //if its a single parameter we dont require paranthese around parameter MyDelegate mydelegate5 = new MyDelegate(name => { Console.WriteLine(name); }); //Lambda expression Step By Step.. Step 4 //if its a single line we dont require curly braces around code and trailing semi colon. //Curly braces are only required for multiline code MyDelegate mydelegate6 = new MyDelegate(name => Console.WriteLine(name)); mydelegate2("Abhishek"); }
C# 3.0 also introduces a new delegate called Func , the typical syntax is like Func<T,TResult>.Consider that last parameter in Func is the return type of method wehere as rest are input to method. Consider below examples:
public class CSharp3O { public delegate void MyDelegate(string name); public Action<string> PrintIt = delegate(string s) { Console.WriteLine(s); } ; public Func<int, int> func = (i) => i * 5; }
So what’s happening here? When we assign a lambda expression to a variable, we end up creating expression trees. Expression trees are powerful and in-memory representation of lambda expression data. This representation allows APIs to exchange information in intuitive way and paved way for transalation frameworks like LINQ to SQL.
We can create expression trees from delegates as well like below.
public class CSharp3O { public delegate void MyDelegate(string name); public Action<string> PrintIt = delegate(string s) { Console.WriteLine(s); } ; public Func<int, int> func = (i) => i * 5; public Expression<Func<int, int>> expression = (i) => i * 5; }
In above code, expression variable hold the representation of data of lambda expression (i) => i * 5 . When we create expressions we only have representation and no executable code but expressions can easily be transformed(Compiled) to excutable code by calling
Func<int,int> func2 = expression.Compile();
Even after all these powerful features, there was one thing that was missing i.e. creating a method at class level without using delegates.
This feature has been added in C# 6.0 as below:
public class CSharp3O { //C# 1.0 public delegate void MyDelegate(string name); //C# 2.0 public Action<string> PrintIt = delegate(string s) { Console.WriteLine(s); } ; //C# 3.0 public Func<int, int> func = (i) => i * 5; public Expression<Func<int, int>> expression = (i) => i * 5; //C# 6.0 public void PrintMe(string name) => Console.WriteLine(name); }So, Guys these are the some of the features of C# 6.0. In our next post we will be discussing our remaining features of C# 6.0.
I Hope in this post I have broadly described each feature of C# which will be helpful to understand the New concepts of C#.
Please share this post with your friends and colleagues. For any queries please post a comment below.
Happy Coding 😉
0 comments:
Post a Comment
If you like this website, please share with your friends on Facebook, Twitter, LinkedIn.