Sunday, July 07, 2013

LINQ 10- Projection/Select- 3

Lazy loading

Linq does few things in background for better performance. One of the important thing is lazy loading. Linq statements or methods are not executed immediately in the very statement. To verify this we can use the following sample class.

public class Employee {
    private string name;
    public string Name {
        get {
            Console.WriteLine("Name Get ");
            return name;
        }
        set {
            name = value;
        }
    }
}

 

In the above code, whenever the Employee name is retrieved it will print the message “Name Get” in the console.

Following code uses the above Employee class for LINQ.

Employee[] employees = new Employee[] {
    new Employee { Name = "John" },
    new Employee { Name = "Bill" },
    new Employee { Name = "Steve" } };
IEnumerable<String> selected = employees.Select(employee => employee.Name);

foreach (String item in selected)
    Console.WriteLine(item);

 

  • In the first statement, we have declared 3 Employees.
  • In the second statement, employee.Name is retrieved from the collection. If the Select method has completed its work in that statement itself, it will get all 3 names and it should print 3 “Name Get” messages. But, it will not, as it is just stores, what needs to be done and not actually doing it.
  • Next, the for each statement prints each names. Meanwhile, to print the names, names should be retrieved from the previous statement. But due to lazy loading,  names are retrieved during MoveNext method’s execution (implicitly done in foreach statement)

Output will be

Name Get
John
Name Get
Bill
Name Get
Steve

Above output clearly shows the Select is not immediately executed.

 

If we print the Type name of “selected” variable, we can see how this is done.

We can use the following statement to check this.

Console.WriteLine(selected.GetType().FullName);

Output

System.Linq.Enumerable+WhereSelectArrayIterator`2[Employee, String]

So during the execution .Net stores the transformation information in the WhereSelectArrayIterator.

WhereSelectArrayIterator class is an internal class, so cannot see the details using Object Browser, but, we can see the details using reflection. We can see this in further posts.

 

We can force the execution of LINQ statements to complete using some other LINQ extensions. Some of them are,

  • ToArray
  • ToList
  • Count

Example

Employee[] employees = new Employee[] {
    new Employee { Name = "John" },
    new Employee { Name = "Bill" },
    new Employee { Name = "Steve" } };
List<String> selected = employees.Select(employee => employee.Name).ToList();

foreach (String item in selected)
    Console.WriteLine(item);

Output

Name Get
Name Get
Name Get
John
Bill
Steve

No comments:

Post a Comment