Getting Ready for .NET 3.5 and LINQ – Exploring C# 3.0 – Part II

Posted by: Manish Sharma , on 8/1/2009, in Category C#
Views: 116509
Abstract: In my previous article Getting Ready for .NET 3.5 and LINQ – Exploring C# 3.0 – Part I, we discussed the first five changes from the list of changes in C# 3.0, mentioned below. This article covers the rest of the changes and is targeted towards users who are planning to migrate to .NET 3.5. With .NET 4.0 around the corner, this article will help you get up to date with C# and will facilitate upgrading to .NET 4.0
Getting Ready for .NET 3.5 and LINQ – Exploring C# 3.0 – Part II
 
In my previous article Getting Ready for .NET 3.5 and LINQ – Exploring C# 3.0 – Part I, we discussed the first five changes from the list of changes in C# 3.0, mentioned below. This article covers the rest of the changes and is targeted towards users who are planning to migrate to .NET 3.5. With .NET 4.0 around the corner, this article will help you get up to date with C# and will facilitate upgrading to .NET 4.0
 
The changes made in C# 3.0 are as follows:
 
     Local Variable Type Inference or Implicitly Typed Local Variables.
     Object Initializers
     Collection Initializers
     Anonymous types
     Auto-implemented properties
     Extension methods
     Lambda expressions
     Query expressions
     Expression trees
     Partial Methods
 
This is a two part article which tells you about the changes which are made in C# 3.0. In this Part (Part II) we are going to see the last five of the above given changes i.e. Extension Methods, Lambda Expressions, Query Expressions, Expression Trees and Partial Methods.
 
So let’s start:
 
Extension Methods:
 
Before C# 3.0, the traditional way of adding methods in the class was by using normal inheritance. Even though the traditional approach offers a better solution in many cases, but we should know how the extension methods work, as they are integral part of LINQ.
 
Extension Methods are static methods which are written in Static classes and the first argument to this method decides to which class object, the method will be called with. The object on which the method is called is automatically passed as a first argument to the method.
 
The rules for adding the extension methods to the class are as follows:
 
1.    Extension Methods must be defined in the Static Classes.
2.    The methods should be public static by nature and should have the first argument as the object of the class to which you want to add the method, prefixed with this.
3.    The class in which the extension methods are written and the class object to which you are adding the extension method should be under the same namespace i.e. they should be the part of the same project.
 
This concept can be used whenever you do not have the codebase to add the functionality into. By using this concept we can get an illusion that we have added a method in the type.
 
Let’s see an example:
 
static void Main(string[] args)
{
      string s = "12345";
      int i = s.ConvertInt(); // Extension Method
      Console.WriteLine(i);
}
 
public static class MyExtensions
{
      public static int ConvertInt(this string s)
      {
            return Convert.ToInt32(s);
      }
}
 
Lambda expressions
 
C# 2.0 came up with a concept called Anonymous Methods. Anonymous Methods were used as follows:
 
          static void Main(string[] args)
      {
            List<string> empList = new List<string>();
            empList.Add("Manish");
            empList.Add("Abhijeet");
            empList.Add("Ramakant");
            empList.Add("Mahaling");
            empList.Add("Varun");
 
            var res = empList.Find(delegate(string n)
            {
                if (n == "Samarth")
                    return true;
                else
                    return false;
            });
 
            if (res == null)
                Console.WriteLine("Name not found in the list.....");
            else
                Console.WriteLine("Name is in the list....");       
}
 
C# 3.0 again comes up with an easier way of writing Anonymous Methods i.e. Lambda Expressions. Lambda Expressions are of two types, Expression Lambda & Statement Lambda. The whole Anonymous concept of 2.0 & 3.0 looks like the following:
 
Anonymous_Concept
 
The difference between Expression Lambda and Statement Lambda is that, the expression Lambda has only one expression; with no curly brace or return statement where as a Statement Lambda is collection of statements.
Example of Lambda Expression:
1.    Expression Lambda
static void Main(string[] args)
      {
            List<string> empList = new List<string>();
            empList.Add("Manish");
            empList.Add("Abhijeet");
            empList.Add("Ramakant");
            empList.Add("Mahaling");
            empList.Add("Varun");
 
            var res = empList.Find(n => n == "Samarth");
 
            if (res == null)
                Console.WriteLine("Name not found in the list.....");
            else
                Console.WriteLine("Name is in the list....");
}
 
How you are going to read it, n is the value which goes into (=>) the method and checks for n is equal to Samarth or not, if it’s equal return true else return false.
Here, the Find() Method returns you the first occurrence (the name) you are checking for, if the condition is true or it returns you null in this case if the name is not in the list.
Here, one string (name) at a time is taken from the list i.e. empList and pushed into the Lamda Expression for checking.
 
2.    Statement Lambda: Statement Lambda on the other hand is collection of statements as follows:
namespace Demo_Lambda
{
    public delegate int AddDelegate(int n);
 
    class Program
    {
        static void Main(string[] args)
        {
            AddEvenNumbers(n =>
            {
                int sum = 0;
                for (int i = 0; i <= n; i++)
                {
                    if (i % 2 == 0)
                    {
                        Console.WriteLine(i);
                        sum += i;
                    }
                }
                return sum;
            });
        }
 
        public static void AddEvenNumbers(AddDelegate d)
        {
            Console.WriteLine("Sum of numbers is: {0}", d(50));
        }
          }
}
 
The above code is going to give you a result as follows:
Sum of numbers is: 650
 
Query Expressions
 
We have gone through many changes in C# 3.0 as a language and all the changes which we have gone through till now is because Microsoft wanted to create an expressive syntax to work with data stored in any data store i.e. Database, Objects, XML file or even Datasets.
So, C# 3.0 change i.e. Query expressions provides a language integrated syntax for writing queries that are similar to queries written in language like SQL (Structured Query Language). Query expressions provide developers a much powerful way than the previous data access methods given in Framework 2.0.
Query Expression is a combination of Query Operators i.e. extension methods and Lambda expressions and can be used over any IEnumerable type.
Query Expressions are written in two ways:
1.    Using Method Syntax: In this syntax, we use Extension Methods provided in System.Linq namespace and pass Lambda Expressions to get the results. In some places it is also termed as ‘Lambda Syntax’.
For example, we want to fetch all Employees who belong to CTD department from the collection empList, Employee class is as follows:
public class Employee
     {
            public int EmpID { get; set; }
            public string EmpName { get; set; }
            public string Department { get; set; }
      }
      So, if we have list of Employees i.e. empList as follows:
      List<Employee> empList = new List<Employee>()
     {
new Employee() { EmpID = 101, EmpName = "Abhijeet Gole", Department = "CTD" },
new Employee() { EmpID = 102, EmpName = "Mahaling Khubba", Department = "Modular" },
new Employee() { EmpID = 102, EmpName = "Pankaj Patil",
Department = "Modular" },
new Employee() { EmpID = 103, EmpName = "Ramakant Debata", Department = "CTD" },
new Employee() { EmpID = 104, EmpName = "Subodh Sohoni", Department = "CTD" },
new Employee() { EmpID = 105, EmpName = "Manish Sharma", Department = "CTD" }
      };
 
Now to fetch all the employees who belong to CTD using the Method syntax, the code will be as follows:
 
var result = empList.Where(e => e.Department == "CTD");
 
And to select only names from the list, the code will be as follows:
 
var result = empList.Where(e => e.Department == "CTD")
                   .Select(e => e.EmpName);
    
2.    Using Declarative Syntax: This is an easier way of writing queries over IEnumerable types because it gives a declarative way of doing the same. Sometimes it is also termed as ‘Comprehension Syntax’.
 
When we are using this syntax, expression begins with ‘from’ clause and ends with a ‘select’ clause. There are multiple other clauses which we can use between ‘from’ clause and ‘select’ clause such as ‘where, orderby, join’.
    
So, taking the previous example, if you want to find all the employees who belong to CTD department, the query will be as follows:
 
var result = from e in empList
                   where e.Department == "CTD"
                   select e;
 
And to select only names from the list:
 
var result = from e in empList
                   where e.Department == "CTD"
                   select e.EmpName;
 
Now one thing worth to metion here is, in both the Syntaxes you are writing LINQ queries, i.e. when you combine multiple Query expressions together, you get LINQ query.
 
Take the previous example i.e.
 
empList.Where(e => e.Department == "CTD")
       .Select(e => e.EmpName);
 
In the above expression we have two query expressions i.e.
 
Where(e => e.Department == "CTD")
 
Select(e => e.EmpName);
 
which are combined to create a single query (LINQ query) so that we can get all the employees who belong to CTD.
There is no execution semantics defined for query expressions written using Declarative Syntax. So how is it executed, how does CLR executes the same?
This discussion is beyond the scope of this article, but to give a brief description, C# 3.0 compiler translates Declarative Syntax expressions into invocations of methods i.e. Method Syntax (Lambda Syntax) and executes them one by one i.e. deferred execution.
In most cases Declarative (Comprehension) syntax is used because it is more readable and short.
 
Expression Trees
 
C# 3.0 gives you a way to treat expressions as data instead of an executable code. So to keep the expressions in the memory in form of data, C# 3.0 introduces a data structure i.e. Expression Trees.
So whenever you want to treat expressions as data, you have to write the expressions in form of Lambda Expressions -- this is one more benefit of Lambda Expressions over Anonymous methods of C# 2.0.
Conversion of Lambda Expression in form of delegate will give an executable code, as follows:
If we have a delegate declaration as follows:
public delegate int AddDelegate(int x, int y);
 
Now when we associate a Lambda expression to the delegate object as follows:
 
AddDelegate d = (a, b) => a + b;
 
And use the delegate object as follows:
 
            int sum = d(20, 30);
Console.WriteLine("Result of addition is: {0}", sum);
 
We will get output as follows which means that the expression is converted to an executable code.
C# 3.0, gives a new type i.e. Expression<T> under System.Linq.Expressions namespace which allows the developers to treat Lambda Expressions as data, allowing for creation and modification of lambda expressions in code.
When a Lambda Expression is converted in form of Expression tree, the data is stored in a tree structure and each node in the expression tree represents an expression. So there are three types of expression tree nodes as follows:
     1.    Binary Expression
2.    Parameter Expression
3.    Constant Expression
 
The following code example will explain all the three; it is similar to an example given on MSDN.
 
 
static void Main(string[] args)
{
     Expression<Func<float, bool>> myExpression = n => (n + 5) < 8;
 
     BinaryExpression expressionBody = (BinaryExpression)myExpression.Body;
    BinaryExpression leftExpression = (BinaryExpression)expressionBody.Left;
    ParameterExpression parameter = (ParameterExpression)leftExpression.Left;
    ConstantExpression five = (ConstantExpression)leftExpression.Right;
    ConstantExpression eight = (ConstantExpression)expressionBody.Right;
 
     Console.WriteLine("Lambda Expression: \t n => (n + 5) < 8\n\n");
     Console.WriteLine("Lambda Expressions Body: \t\t{0}", expressionBody);
Console.WriteLine("Left Binary Expression in Body: \t{0}", leftExpression);
    Console.WriteLine("Lambda Expression Parameter: \t\t{0}", parameter);
    Console.WriteLine("Constant in Left Expression: \t\t{0}", five);
     Console.WriteLine("Constant in Expression Body: \t\t{0}", eight);
    Console.ReadLine();
}
 
The output of the above is:
 
Lambda Expression:   n => (n + 5) < 8
 
Lambda Expressions Body:               ((n + 5) < 8)
Left Binary Expression in Body:        (n + 5)
Lambda Expression Parameter:           n
Constant in Left Expression:           5
Constant in Expression Body:           8
 
You can also get an executable code by compiling the Expression tree as follows:
 
var myFunction = myExpression.Compile();
      Console.WriteLine("\n\nResult: {0}", myFunction(2));
 
Output
 
   Result: True  
 
Partial Methods
 
Partial methods are the methods which can be declared or defined only inside a partial class and gets emitted inside the assembly (MSIL) only when it has an implementation. Implementation of partial methods is not compulsory so, if it is not implemented, the compiler removes all the instances from the MSIL.
Before using partial methods you should take the following points into consideration:
1)      Partial methods are implicitly private and cannot apply any other access modifier.
2)      Partial methods should be defined in a partial class.
3)      Partial methods must be prefixed with Partial keyword.
4)      Partial methods should not return any value, they should be void.
5)      Out modifier is not allowed in partial methods.
6)      Partial methods can be static or instance level.
 
Partial methods help to increase the performance, as at the time of execution, the methods which are not implemented are not available in MSIL, so they will not be loaded. Partial methods are used in LINQ to SQL classes.
 
The example given below is not a very realistic example, but it can explain the concept:
 
For example, we have the following Employee class
 
public partial class Employee
{
     public int EmpID { get; set; }
     public string EmpName { get; set; }
     public string Department { get; set; }
 
     void WriteOnConsole()
     {
         Console.WriteLine("Employee ID: {0}", EmpID);
         Console.WriteLine("Employee Name: {0}", EmpName);
         Console.WriteLine("Employee Department: {0}", Department);
     }
 
     partial void WriteOnFile();
 
     public void ShowData()
     {
         WriteOnConsole();
         WriteOnFile();
     }
}
 
So, when we create an object of this class and call the ShowData() method, it just writes the data on the Console, because WriteOnFile() does not have any definition, the method and method call is removed from the MSIL by the compiler.
 
So when we use the class as follows:
 
Employee e1 = new Employee()
{
EmpID = 101, EmpName = "Manish", Department = "CTD"
};
      e1.ShowData();
 
It just displays the data on the console, as follows:
 
     Employee ID: 101
     Employee Name: Manish
     Employee Department: CTD
 
But afterwards, if you want to implement the WriteOnFile() method, just add another class file with partial class employee and implement the partial method after this recompile the project, Employee class with WirtteOnFile(), is as follows:
 
public partial class Employee
{
     partial void WriteOnFile()
    {
          StreamWriter sw = new StreamWriter("C:\\Employee.txt", true);
         sw.WriteLine("Employee ID: {0}", EmpID);
         sw.WriteLine("Employee Name: {0}", EmpName);
         sw.WriteLine("Employee Department: {0}", Department);
         Console.WriteLine("\n\nData written to File.......");
         sw.Close();
    }
}
 
And just recompile now because you have implemented the method. C# compiler will add the method and the call in the MSIL. So after this if you run the application again you will get the following output:
 
     Employee ID: 101
     Employee Name: Manish
     Employee Department: CTD
 
     Data written to File.......
 
With Employee.txt file containing the same data on C drive of your machine.
 
Conclusion
 
So in this article, we explored the next five features introduced in C# 3.0. I hope the two parts series have helped you in understanding the new changes introduced in C# 3.0 as a language and will help you deep dive into LINQ. With .NET 4.0 around the corner
Manish Sharma, PGDCA, MCA, is a Freelance consultant. Manish has over 8+ years of experience in IT education and development. He is a Microsoft Certified Trainer (MCT) and has conducted various Public Batches & Corporate Training programs in all .NET Technologies.

This article has been editorially reviewed by Suprotim Agarwal.

Absolutely Awesome Book on C# and .NET

C# and .NET have been around for a very long time, but their constant growth means there’s always more to learn.

We at DotNetCurry are very excited to announce The Absolutely Awesome Book on C# and .NET. This is a 500 pages concise technical eBook available in PDF, ePub (iPad), and Mobi (Kindle).

Organized around concepts, this Book aims to provide a concise, yet solid foundation in C# and .NET, covering C# 6.0, C# 7.0 and .NET Core, with chapters on the latest .NET Core 3.0, .NET Standard and C# 8.0 (final release) too. Use these concepts to deepen your existing knowledge of C# and .NET, to have a solid grasp of the latest in C# and .NET OR to crack your next .NET Interview.

Click here to Explore the Table of Contents or Download Sample Chapters!

What Others Are Reading!
Was this article worth reading? Share it with fellow developers too. Thanks!
Share on LinkedIn
Share on Google+

Author
Author bio not available


Page copy protected against web site content infringement 	by Copyscape




Feedback - Leave us some adulation, criticism and everything in between!
Comment posted by Jyoti Ghadge on Monday, August 3, 2009 5:04 AM
Gr8 Article. Looking Forward for such articles.
Comment posted by Varun on Monday, August 3, 2009 5:19 AM
Hey Manish thanks this is really a good article.Hope You will post more on LINQ.