Csharp/C Sharp/LINQ/Deferred Query

Материал из .Net Framework эксперт
Перейти к: навигация, поиск

A deferred execution query is reevaluated when you reenumerate:

 
using System;
using System.Collections.Generic;
using System.Linq;
public class MainClass {
    public static void Main() {
        var numbers = new List<int>() { 1, 2 };
        IEnumerable<int> query = numbers.Select(n => n * 10);
        foreach (int n in query) Console.Write(n + "|"); 
        numbers.Clear();
        foreach (int n in query) Console.Write(n + "|"); 
    }
}


Deferred Query Execution

 
using System;
using System.Linq;
class MainClass {
    static double Square(double n) {
        return Math.Pow(n, 2);
    }
    public static void Main() {
        int[] numbers = { 1, 2, 3 };
        var query = from n in numbers select Square(n);
        foreach (var n in query)
            Console.WriteLine(n);
    }
}


Deferred Query Execution: shows how query execution is deferred until the query is enumerated at a foreach statement.

 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
public class MainClass {
    public static void Main() {
        int[] numbers = new int[] { 5, 4, 1, 3, 9 };
        int i = 0;
        var q =
            from n in numbers
            select ++i;
        foreach (var v in q) {
            Console.WriteLine("v = {0}, i = {1}", v, i);
        }
    }
}


How queries can be executed immediately with operators such as ToList().

 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
public class MainClass {
    public static void Main() {
        int[] numbers = new int[] { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
        int i = 0;
        var q = (
            from n in numbers
            select ++i)
            .ToList();
        // The local variable i has already been fully
        // incremented before we iterate the results:
        foreach (var v in q) {
            Console.WriteLine("v = {0}, i = {1}", v, i);
        }
    }
}


Immediate Query Execution

 
using System;
using System.Linq;
class MainClass {
    static double Square(double n) {
        Console.WriteLine("Computing Square(" + n + ")...");
        return Math.Pow(n, 2);
    }
    public static void Main() {
        int[] numbers = { 1, 2, 3 };
        var query = from n in numbers select Square(n);
        foreach (var n in query.ToList())
            Console.WriteLine(n);
    }
}


most query operators is that they execute not when constructed, but when enumerated

 
using System;
using System.Collections.Generic;
using System.Linq;
public class MainClass {
    public static void Main() {
        var numbers = new List<int>();
        numbers.Add(1);
        IEnumerable<int> query = numbers.Select(n => n * 10);
        numbers.Add(2);             
        foreach (int n in query)
            Console.Write(n + "|"); 
    }
}


Shows how queries can be reused

 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
public class MainClass {
    public static void Main() {
        int[] numbers = new int[] { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
        var lowNumbers =
            from n in numbers
            where n <= 3
            select n;
        Console.WriteLine("First run numbers <= 3:");
        foreach (int n in lowNumbers) {
            Console.WriteLine(n);
        }
        for (int i = 0; i < 10; i++) {
            numbers[i] = -numbers[i];
        }
        Console.WriteLine("Second run numbers <= 3:");
        foreach (int n in lowNumbers) {
            Console.WriteLine(n);
        }
    }
}