Lazy Evaluation behaves in a surprising way in LINQ, look at an example. First, consider the following Boolean function that as a side-effect outputs the doctor's initials:

public static bool dump(Doctor d)
{
    System.Console.WriteLine(d.Initials);
    return true;
}

Now use dump in a simple query that will end up selecting all the doctors because the function always returns true:

var query = from d in doctors
            where dump(d)
            select d;

Interestingly, until here the query outputs nothing, in fact, the query has not been evaluated yet. What happened is evaluation in most cases is delayed until the results of the query are actually requested, an approach known as lazy evaluation.

Advantages:

1. One of the implications of LINQ's lazy evaluation is that query expressions are re-evaluated each time they are processed. In other words, the results of a query are not stored or cached in a collection, but lazily evaluated and returned on each request. The advantage is that changes in the data are automatically reflected in the next processing cycle:

foreach (var result in query)    // outputs initials for all doctors
    ;
doctors.Add( new Doctor("xyz", ...) )
    ;
foreach (var result in query)    // output now includes new doctor "xyz"
    ;

2.

Another advantage is that complex queries can be constructed from simpler ones, and execution is delayed until the final query is ready (and possibly optimized!).

If you want to force immediate query evaluation and cache the results, the simplest approach is to call the ToArray or ToListmethods on the query. For example, the following code fragment outputs the initials of all doctors three consecutive times:

 var cache1 = query.ToArray();  // evaluate query & cache results as an array

 doctors.Add( new Doctor("xyz", ...) );

 System.Console.WriteLine("#########");
 var cache2 = query.ToList();   // evaluate query again & cache results as a list

 System.Console.WriteLine("#########");
 System.Console.WriteLine( cache1.GetType() );
 System.Console.WriteLine( cache2.GetType() );

 foreach (var result in cache1)  // output results of initial query:
     System.Console.WriteLine(result.Initials);
 System.Console.WriteLine("#########");

The second cache contains the new doctor, but the first does not. Here's the output:

mbl
jl
.
.
ks
#########
mbl
jl
.
.
ks
xyz
#########
Doctor[]
System.Collections.Generic.List`1[Doctor]
mbl
jl
.
.
ks
#########
posted on 2011-08-05 09:54  lochker  阅读(404)  评论(0编辑  收藏  举报