Much of Linq's query operators are method extensions which take a typed iterator for input, and return a modified iterator of the same time as their output.
List<Client> clients = new List<Client>();
IEnumerable<Client> it1 = clients as IEnumerable<Client>;
IEnumerable<Client> it2 = it1.Where(c => c.Rating > 5);
This pattern allows for the piping of multiple query operators, the first one's output providing the next one's input :
List<Client> clients = new List<Client>();
IEnumerable<Client> it1 = clients as IEnumerable<Client>;
IEnumerable<Client> it2 = it1.Where(c => c.Rating > 5); IEnumerable<Client> it3 = it2.Where(c => c.Rating < 10);
IEnumerable<Client> it4 = it3.Where(c => c.Rating != 7);
The fact that Linq's query operators are built from iterators has important implications, as it enables the deferred evaluation of a query. That is because C# iterators only return their elements when they are asked for. For example, the following iterator will only perform it's first time consuming operation :
public IEnumerable<int> GetItems()
{
yield return this.TimeConsumingOperation(1);
yield return this.TimeConsumingOperation(2);
yield return this.TimeConsumingOperation(3);
}
foreach (int item in iterator.GetItems())
{
int firstItem = item;
break;
}
This means that a query operation will only be evaluated when its items are iterated over, and for only as many items as the iteration asks for.
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment