101 LINQ Samples

 转自MSDN

Restriction Operators
  • Where - Simple 1

    public void Linq1() {
        int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
        var lowNums =
            from n in numbers
            where n < 5
            select n;
        Console.WriteLine("Numbers < 5:");
        foreach (var x in lowNums) {
            Console.WriteLine(x);
        }
    }

  • Where - Simple 2

    public void Linq2() {
        List products = GetProductList();
        var soldOutProducts =
            from p in products
            where p.UnitsInStock == 0
            select p;
        Console.WriteLine("Sold out products:");
        foreach (var product in soldOutProducts) {
            Console.WriteLine("{0} is sold out!", product.ProductName);
        }
    }

  • Where - Simple 3

    public void Linq3() {
        List products = GetProductList();
        var expensiveInStockProducts =
            from p in products
            where p.UnitsInStock > 0 && p.UnitPrice > 3.00M
            select p;
        Console.WriteLine("In-stock products that cost more than 3.00:");
        foreach (var product in expensiveInStockProducts) {
            Console.WriteLine("{0} is in stock and costs more than 3.00.", product.ProductName);
        }
    }

  • Where - Drilldown

    public void Linq4() {
        List customers = GetCustomerList();
        var waCustomers =
            from c in customers
            where c.Region == "WA"
            select c;
        Console.WriteLine("Customers from Washington and their orders:");
        foreach (var customer in waCustomers) {
            Console.WriteLine("Customer {0}: {1}", customer.CustomerID, customer.CompanyName);
            foreach (var order in customer.Orders) {
                Console.WriteLine(" Order {0}: {1}", order.OrderID, order.OrderDate);
            }
        }
    }

  • Where - Indexed

    public void Linq5() {
        string[] digits = { "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine" };
        var shortDigits = digits.Where((digit, index) => digit.Length < index);
        Console.WriteLine("Short digits:");
        foreach (var d in shortDigits) {
            Console.WriteLine("The word {0} is shorter than its value.", d);
        }
    }

Projection Operators
  • Select - Simple 1

    public void Linq6() {
        int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
        var numsPlusOne =
            from n in numbers
            select n + 1;
        Console.WriteLine("Numbers + 1:");
        foreach (var i in numsPlusOne) {
            Console.WriteLine(i);
        }
    }

  • Select - Simple 2

    public void Linq7() {
        List products = GetProductList();
        var productNames =
            from p in products
            select p.ProductName;
        Console.WriteLine("Product Names:");
        foreach (var productName in productNames) {
            Console.WriteLine(productName);
        }
    }

  • Select - Transformation

    public void Linq8() {
        int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
        string[] strings = { "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine" };
        var textNums =
            from n in numbers
            select strings[n];
        Console.WriteLine("Number strings:");
        foreach (var s in textNums) {
            Console.WriteLine(s);
        }        
    }

  • Select - Anonymous Types 1

    public void Linq9() {
        string[] words = { "aPPLE", "BlUeBeRrY", "cHeRry" };
        var upperLowerWords =
            from w in words
            select new {Upper = w.ToUpper(), Lower = w.ToLower()};
        foreach (var ul in upperLowerWords) {
            Console.WriteLine("Uppercase: {0}, Lowercase: {1}", ul.Upper, ul.Lower);
        }
    }

  • Select - Anonymous Types 2

    public void Linq10() {
        int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
        string[] strings = { "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine" };
        var digitOddEvens =
            from n in numbers
            select new {Digit = strings[n], Even = (n % 2 == 0)};
        foreach (var d in digitOddEvens) {
            Console.WriteLine("The digit {0} is {1}.", d.Digit, d.Even ? "even" : "odd");
        }
    }

  • Select - Anonymous Types 3

    public void Linq11() {
        List products = GetProductList();
        var productInfos =
            from p in products
            select new {p.ProductName, p.Category, Price = p.UnitPrice};
        Console.WriteLine("Product Info:");
        foreach (var productInfo in productInfos) {
            Console.WriteLine("{0} is in the category {1} and costs {2} per unit.", productInfo.ProductName, productInfo.Category, productInfo.Price);
        }
    }

  • Select - Indexed

    public void Linq12() {
        int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
        var numsInPlace = numbers.Select((num, index) => new {Num = num, InPlace = (num == index)});
        Console.WriteLine("Number: In-place?");
        foreach (var n in numsInPlace) {
            Console.WriteLine("{0}: {1}", n.Num, n.InPlace);
        }
    }

  • Select - Filtered

    public void Linq13() {
        int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
        string[] digits = { "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine" };
        var lowNums =
            from n in numbers
            where n < 5
            select digits[n];
        Console.WriteLine("Numbers < 5:");
        foreach (var num in lowNums) {
            Console.WriteLine(num);
        }    
    }

  • SelectMany - Compound from 1

    public void Linq14() {
        int[] numbersA = { 0, 2, 4, 5, 6, 8, 9 };
        int[] numbersB = { 1, 3, 5, 7, 8 };
        var pairs =
            from a in numbersA,
                    b in numbersB
            where a < b
            select new {a, b};
        Console.WriteLine("Pairs where a < b:");
        foreach (var pair in pairs) {
            Console.WriteLine("{0} is less than {1}", pair.a, pair.b);
        }
    }

  • SelectMany - Compound from 2

    public void Linq15() {
        List customers = GetCustomerList();
        var orders =
            from c in customers,
                    o in c.Orders
            where o.Total < 500.00M
            select new {c.CustomerID, o.OrderID, o.Total};
        ObjectDumper.Write(orders);
    }

  • SelectMany - Compound from 3

    public void Linq16() {
        List customers = GetCustomerList();
        var orders =
            from c in customers,
                    o in c.Orders
            where o.OrderDate >= new DateTime(1998, 1, 1)
            select new {c.CustomerID, o.OrderID, o.OrderDate};
        ObjectDumper.Write(orders);
    }

  • SelectMany - from Assignment

    public void Linq17() {
        List customers = GetCustomerList();
        var orders =
            from c in customers,
                    o in c.Orders,
                    total = o.Total
            where total >= 2000.0M
            select new {c.CustomerID, o.OrderID, total};
        ObjectDumper.Write(orders);
    }

  • SelectMany - Multiple from

    public void Linq18() {
        List customers = GetCustomerList();
        DateTime cutoffDate = new DateTime(1997, 1, 1);
        var orders =
            from c in customers
            where c.Region == "WA"
            from o in c.Orders
            where o.OrderDate >= cutoffDate
            select new {c.CustomerID, o.OrderID};
        ObjectDumper.Write(orders);
    }

  • SelectMany - Indexed

    public void Linq19() {
        List customers = GetCustomerList();
        var customerOrders =
            customers.SelectMany(
                (cust, custIndex) =>
                cust.Orders.Select(o => "Customer #" + (custIndex + 1) +
                                        " has an order with OrderID " + o.OrderID) );
        ObjectDumper.Write(customerOrders);
    }

Partitioning Operators
  • Take - Simple

    public void Linq20() {
                int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
                var first3Numbers = numbers.Take(3);
                Console.WriteLine("First 3 numbers:");
                foreach (var n in first3Numbers) {
                    Console.WriteLine(n);
                }
            }

  • Take - Nested

    public void Linq21() {
                List<Customer> customers = GetCustomerList();
                var first3WAOrders = (
                    from c in customers
                    from o in c.Orders
                    where c.Region == "WA"
                    select new {c.CustomerID, o.OrderID, o.OrderDate} )
                    .Take(3);
                Console.WriteLine("First 3 orders in WA:");
                foreach (var order in first3WAOrders) {
                    ObjectDumper.Write(order);
                }
            }

  • Skip - Simple

    public void Linq22() {
                int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
                var allButFirst4Numbers = numbers.Skip(4);
                Console.WriteLine("All but first 4 numbers:");
                foreach (var n in allButFirst4Numbers) {
                    Console.WriteLine(n);
                }
            }

  • Skip - Nested

    public void Linq23() {
                List<Customer> customers = GetCustomerList();
                var waOrders =
                    from c in customers
                    from o in c.Orders
                    where c.Region == "WA"
                    select new {c.CustomerID, o.OrderID, o.OrderDate};
                var allButFirst2Orders = waOrders.Skip(2);
                Console.WriteLine("All but first 2 orders in WA:");
                foreach (var order in allButFirst2Orders) {
                    ObjectDumper.Write(order);
                }
            }

  • TakeWhile - Simple

    public void Linq24() {
                int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
                var firstNumbersLessThan6 = numbers.TakeWhile(n => n < 6);
                Console.WriteLine("First numbers less than 6:");
                foreach (var n in firstNumbersLessThan6) {
                    Console.WriteLine(n);
                }
            }

  • SkipWhile - Simple

    public void Linq26() {
                int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
                var allButFirst3Numbers = numbers.SkipWhile(n => n % 3 != 0);
                Console.WriteLine("All elements starting from first element divisible by 3:");
                foreach (var n in allButFirst3Numbers) {
                    Console.WriteLine(n);
                }
            }

  • SkipWhile - Indexed

    public void Linq27() {
                int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
                var laterNumbers = numbers.SkipWhile((n, index) => n >= index);
                Console.WriteLine("All elements starting from first element less than its position:");
                foreach (var n in laterNumbers) {
                    Console.WriteLine(n);
                }
            }

Ordering Operators
  • OrderBy - Simple 1
    publicvoid Linq28() {    string[] words = { "cherry", "apple", "blueberry" };        var sortedWords =        from w in words        orderby w        select w;        Console.WriteLine("The sorted list of words:");    foreach (var w in sortedWords) {        Console.WriteLine(w);    }}
  • OrderBy - Simple 2

    public void Linq29() {
        string[] words = { "cherry", "apple", "blueberry" };
        var sortedWords =
            from w in words
            orderby w.Length
            select w;
        Console.WriteLine("The sorted list of words (by length):");
        foreach (var w in sortedWords) {
            Console.WriteLine(w);
        }
    }

  • OrderBy - Simple 3

    public void Linq30() {
        List products = GetProductList();
        var sortedProducts =
            from p in products
            orderby p.ProductName
            select p;
        ObjectDumper.Write(sortedProducts);
    }

  • OrderBy - Comparer

    public class CaseInsensitiveComparer : IComparer<string>
    {
        public int Compare(string x, string y)
        {
            return string.Compare(x, y, true);
        }
    }
    public void Linq31() {
        string[] words = { "aPPLE", "AbAcUs", "bRaNcH", "BlUeBeRrY", "ClOvEr", "cHeRry"};
        var sortedWords = words.OrderBy(a => a, new CaseInsensitiveComparer());
        ObjectDumper.Write(sortedWords);
    }

  • OrderByDescending - Simple 1

    public void Linq32() {
        double[] doubles = { 1.7, 2.3, 1.9, 4.1, 2.9 };
        var sortedDoubles =
            from d in doubles
            orderby d descending
            select d;
        Console.WriteLine("The doubles from highest to lowest:");
        foreach (var d in sortedDoubles) {
            Console.WriteLine(d);
        }
    }

  • OrderByDescending - Simple 2

    public void Linq33() {
        List products = GetProductList();
        var sortedProducts =
            from p in products
            orderby p.UnitsInStock descending
            select p;
        ObjectDumper.Write(sortedProducts);
    }

  • OrderByDescending - Comparer
    public class CaseInsensitiveComparer : IComparerspan class="qs-keyword">string>{    publicint Compare(string x, string y)    {        returnstring.Compare(x, y, true);    }}publicvoid Linq34() {    string[] words = { "aPPLE", "AbAcUs", "bRaNcH", "BlUeBeRrY", "ClOvEr", "cHeRry"};        var sortedWords = words.OrderByDescending(a => a, new CaseInsensitiveComparer());            ObjectDumper.Write(sortedWords);}
  • ThenBy - Simple
    publicvoid Linq35() {    string[] digits = { "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine" };    var sortedDigits =        from d in digits         orderby d.Length, d        select d;    Console.WriteLine("Sorted digits:");    foreach (var d in sortedDigits) {        Console.WriteLine(d);    }}
  • ThenBy - Comparer
    public class CaseInsensitiveComparer : IComparerspan class="qs-keyword">string>{    publicint Compare(string x, string y)    {        returnstring.Compare(x, y, true);    }}publicvoid Linq36() {    string[] words = { "aPPLE", "AbAcUs", "bRaNcH", "BlUeBeRrY", "ClOvEr", "cHeRry"};        var sortedWords =        words.OrderBy(a => a.Length)                .ThenBy(a => a, new CaseInsensitiveComparer());            ObjectDumper.Write(sortedWords);}
  • ThenByDescending - Simple
    publicvoid Linq37() {    List products = GetProductList();var sortedProducts =        from p in products        orderby p.Category, p.UnitPrice descendingselect p;    ObjectDumper.Write(sortedProducts);}
  • ThenByDescending - Comparer
    public class CaseInsensitiveComparer : IComparerspan class="qs-keyword">string>{    publicint Compare(string x, string y)    {        returnstring.Compare(x, y, true);    }}publicvoid Linq38() {    string[] words = { "aPPLE", "AbAcUs", "bRaNcH", "BlUeBeRrY", "ClOvEr", "cHeRry"};        var sortedWords =        words.OrderBy(a => a.Length)                .ThenByDescending(a => a, new CaseInsensitiveComparer());            ObjectDumper.Write(sortedWords);}
  • Reverse
    publicvoid Linq39() {    string[] digits = { "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine" };        var reversedIDigits = (        from d in digits        where d[1] == 'i'        select d)        .Reverse();        Console.WriteLine("A backwards list of the digits with a second character of 'i':");    foreach (var d in reversedIDigits) {        Console.WriteLine(d);    }             }
Grouping Operators
  • GroupBy - Simple 1

    public void Linq40() {
                int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
                var numberGroups =
                    from n in numbers
                    group n by n % 5 into g
                    select new { Remainder = g.Key, Numbers = g };
                foreach (var g in numberGroups) {
                    Console.WriteLine("Numbers with a remainder of {0} when divided by 5:", g.Remainder);
                    foreach (var n in g.Numbers) {
                        Console.WriteLine(n);
                    }
                }
    }

  • GroupBy - Simple 2

    public void Linq41() {
                string[] words = { "blueberry", "chimpanzee", "abacus", "banana", "apple", "cheese" };
                var wordGroups =
                    from w in words
                    group w by w[0] into g
                    select new { FirstLetter = g.Key, Words = g };
                foreach (var g in wordGroups) {
                    Console.WriteLine("Words that start with the letter '{0}':", g.FirstLetter);
                    foreach (var w in g.Words) {
                        Console.WriteLine(w);
                    }
                }
            }

  • GroupBy - Simple 3

    public void Linq42() {
                List<Product> products = GetProductList();
                var orderGroups =
                    from p in products
                    group p by p.Category into g
                    select new { Category = g.Key, Products = g };
                ObjectDumper.Write(orderGroups, 1);
            }

  • GroupBy - Nested

    public void Linq43() {
                List<Customer> customers = GetCustomerList();
                var customerOrderGroups =
                    from c in customers
                    select
                        new {c.CompanyName,
                             YearGroups =
                                 from o in c.Orders
                                 group o by o.OrderDate.Year into yg
                                 select
                                     new {Year = yg.Key,
                                          MonthGroups =
                                              from o in yg
                                              group o by o.OrderDate.Month into mg
                                              select new { Month = mg.Key, Orders = mg }
                                         }
                            };
                ObjectDumper.Write(customerOrderGroups, 3);
            }

  • GroupBy - Comparer
    public class AnagramEqualityComparer : IEqualityComparer 
    {
    public bool Equals(string x, string y) { return getCanonicalString(x) == getCanonicalString(y); }
    public int GetHashCode(string obj) { return getCanonicalString(obj).GetHashCode(); }
    private string getCanonicalString(string word)
    {
    char[] wordChars = word.ToCharArray(); Array.Sort(wordChars); return new string(wordChars);
    }
    }


    publicvoid Linq44() 
    {
    string[] anagrams = {"from ", " salt", " earn ", " last ", " near ", " form "};
    var orderGroups = anagrams.GroupBy(w => w.Trim(), new AnagramEqualityComparer());
    ObjectDumper.Write(orderGroups, 1);
    }
  • GroupBy - Comparer, Mapped

    public void Linq45() {
                string[] anagrams = {"from ", " salt", " earn ", " last ", " near ", " form "};
                var orderGroups = anagrams.GroupBy(
                            w => w.Trim(),
                            a => a.ToUpper(),
                            new AnagramEqualityComparer()
                            );
                ObjectDumper.Write(orderGroups, 1);
            }
    public class AnagramEqualityComparer : IEqualityComparer<string>
            {
                public bool Equals(string x, string y) {
                    return getCanonicalString(x) == getCanonicalString(y);
                }
                public int GetHashCode(string obj) {
                    return getCanonicalString(obj).GetHashCode();
                }
                private string getCanonicalString(string word) {
                    char[] wordChars = word.ToCharArray();
                    Array.Sort<char>(wordChars);
                    return new string(wordChars);
                }
            }

Set Operators
  • Distinct - 1
    publicvoid Linq46() {    int[] factorsOf300 = { 2, 2, 3, 5, 5 };        var uniqueFactors = factorsOf300.Distinct();    Console.WriteLine("Prime factors of 300:");    foreach (var f in uniqueFactors) {        Console.WriteLine(f);    }}
  • Distinct - 2
    public void Linq47() {    List products = GetProductList();
    var categoryNames = ( from p in products select p.Category) .Distinct(); Console.WriteLine("Category names:"); foreach (var n in categoryNames) { Console.WriteLine(n); }}
  • Union - 1
    publicvoid Linq48() {    int[] numbersA = { 0, 2, 4, 5, 6, 8, 9 };    int[] numbersB = { 1, 3, 5, 7, 8 };        var uniqueNumbers = numbersA.Union(numbersB);        Console.WriteLine("Unique numbers from both arrays:");    foreach (var n in uniqueNumbers) {        Console.WriteLine(n);    }}
  • Union - 2
    publicvoid Linq49() {    List products = GetProductList();List customers = GetCustomerList();        var productFirstChars =        from p in products        select p.ProductName[0];    var customerFirstChars =        from c in customers        select c.CompanyName[0];        var uniqueFirstChars = productFirstChars.Union(customerFirstChars);        Console.WriteLine("Unique first letters from Product names and Customer names:");    foreach (var ch in uniqueFirstChars) {        Console.WriteLine(ch);    }}
  • Intersect - 1
    publicvoid Linq50() {    int[] numbersA = { 0, 2, 4, 5, 6, 8, 9 };    int[] numbersB = { 1, 3, 5, 7, 8 };        var commonNumbers = numbersA.Intersect(numbersB);        Console.WriteLine("Common numbers shared by both arrays:");    foreach (var n in commonNumbers) {        Console.WriteLine(n);    }}
  • Intersect - 2
    publicvoid Linq51() {    List products = GetProductList();
    List customers = GetCustomerList(); var productFirstChars = from p in products select p.ProductName[0]; var customerFirstChars = from c in customers select c.CompanyName[0]; var commonFirstChars = productFirstChars.Intersect(customerFirstChars); Console.WriteLine("Common first letters from Product names and Customer names:"); foreach (var ch in commonFirstChars) { Console.WriteLine(ch); }}
  • Except - 1

    public void Linq52() {
        int[] numbersA = { 0, 2, 4, 5, 6, 8, 9 };
        int[] numbersB = { 1, 3, 5, 7, 8 };
        IEnumerable<int> aOnlyNumbers = numbersA.Except(numbersB);
        Console.WriteLine("Numbers in first array but not second array:");
        foreach (var n in aOnlyNumbers) {
            Console.WriteLine(n);
        }
    }

  • Except - 2

    public void Linq53() {
        List products = GetProductList();
        List customers = GetCustomerList();
        var productFirstChars =
            from p in products
            select p.ProductName[0];
        var customerFirstChars =
            from c in customers
            select c.CompanyName[0];
        var productOnlyFirstChars = productFirstChars.Except(customerFirstChars);
        Console.WriteLine("First letters from Product names, but not from Customer names:");
        foreach (var ch in productOnlyFirstChars) {
            Console.WriteLine(ch);
        }
    }

Conversion Operators
  • To Array

    public void Linq54() {
        double[] doubles = { 1.7, 2.3, 1.9, 4.1, 2.9 };
        var sortedDoubles =
            from d in doubles
            orderby d descending
            select d;
        var doublesArray = sortedDoubles.ToArray();
        Console.WriteLine("Every other double from highest to lowest:");
        for (int d = 0; d < doublesArray.Length; d += 2) {
            Console.WriteLine(doublesArray[d]);
        }
    }

  • To List

    public void Linq55() {
        string[] words = { "cherry", "apple", "blueberry" };
        var sortedWords =
            from w in words
            orderby w
            select w;
        var wordList = sortedWords.ToList();
        Console.WriteLine("The sorted word list:");
        foreach (var w in wordList) {
            Console.WriteLine(w);
        }
    }

  • To Dictionary

    public void Linq56() {
        var scoreRecords = new [] { new {Name = "Alice", Score = 50},
                                    new {Name = "Bob" , Score = 40},
                                    new {Name = "Cathy", Score = 45}
                                  };
        var scoreRecordsDict = scoreRecords.ToDictionary(sr => sr.Name);
        Console.WriteLine("Bob's score: {0}", scoreRecordsDict["Bob"]);
    }

  • OfType

    public void Linq57() {
        object[] numbers = { null, 1.0, "two", 3, 4.0f, 5, "six", 7.0 };
        var doubles = numbers.OfType<double>();
        Console.WriteLine("Numbers stored as doubles:");
        foreach (var d in doubles) {
            Console.WriteLine(d);
        }
    }

Element Operators
  • First - Simple

    public void Linq58() {
        List products = GetProductList();
        Product product12 = (
            from p in products
            where p.ProductID == 12
            select p )
            .First();
        ObjectDumper.Write(product12);
    }

  • First - Indexed

    public void Linq60() {
        int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
        int evenNum = numbers.First((num, index) => (num % 2 == 0) && (index % 2 == 0));
        Console.WriteLine("{0} is an even number at an even position within the list.", evenNum);
    }

  • FirstOrDefault - Simple

    public void Linq61() {
        int[] numbers = {};
        int firstNumOrDefault = numbers.FirstOrDefault();
        Console.WriteLine(firstNumOrDefault);
    }

  • FirstOrDefault - Condition

    public void Linq62() {
        List products = GetProductList();
        Product product789 = products.FirstOrDefault(p => p.ProductID == 789);
        Console.WriteLine("Product 789 exists: {0}", product789 != null);
    }

  • FirstOrDefault - Indexed

    public void Linq63() {
        double?[] doubles = { 1.7, 2.3, 4.1, 1.9, 2.9 };
        double? num = doubles.FirstOrDefault((n, index) => (n >= index - 0.5 && n <= index + 0.5));
        if (num != null)
            Console.WriteLine("The value {1} is within 0.5 of its index position.", num);
        else
            Console.WriteLine("There is no number within 0.5 of its index position.", num);
    }

  • ElementAt

    public void Linq64() {
        int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
        int fourthLowNum = (
            from n in numbers
            where n < 5
            select n )
            .ElementAt(3); // 3 because sequences use 0-based indexing
        Console.WriteLine("Fourth number < 5: {0}", fourthLowNum);
    }

Generation Operators
  • Range

    public void Linq65() {
       var numbers =
          from n in Sequence.Range(100, 50)
          selectnew {Number = n, OddEven = n % 2 == 1 ? "odd" : "even"};
       foreach (var n in numbers) {
          Console.WriteLine("The number {0} is {1}.", n.Number, n.OddEven);
       }
    }

  • Repeat

    public void Linq66() {
       var numbers = Sequence.Repeat(7, 10);
       foreach (var n in numbers) {
          Console.WriteLine(n);
       }
    }

Quantifiers
  • Any - Simple

    public void Linq67() {
       string[] words = { "believe", "relief", "receipt", "field" };
       bool iAfterE = words.Any(w => w.Contains("ei"));
       Console.WriteLine("There is a word that contains in the list that contains 'ei': {0}", iAfterE);
    }

  • Any - Indexed

    public void Linq68() {
       int[] numbers = { -9, -4, -8, -3, -5, -2, -1, -6, -7 };
       bool negativeMatch = numbers.Any((n, index) => n == -index);
       Console.WriteLine("There is a number that is the negative of its index: {0}", negativeMatch);
    }

  • Any - Grouped

    public void Linq69() {
       List products = GetProductList();
       var productGroups =
          from p in products
          group p by p.Category into g
          where g.Group.Any(p => p.UnitsInStock == 0)
          select new {Category = g.Key, Products = g.Group};
       ObjectDumper.Write(productGroups, 1);
    }

  • All - Simple

    public void Linq70() {
       int[] numbers = { 1, 11, 3, 19, 41, 65, 19 };
       bool onlyOdd = numbers.All(n => n % 2 == 1);
       Console.WriteLine("The list contains only odd numbers: {0}", onlyOdd);
    }

  • All - Indexed

    public void Linq71() {
       int[] lowNumbers = { 1, 11, 3, 19, 41, 65, 19 };
       int[] highNumbers = { 7, 19, 42, 22, 45, 79, 24 };
       bool allLower = lowNumbers.All((num, index) => num < highNumbers[index]);
       Console.WriteLine("Each number in the first list is lower than its counterpart in the second list: {0}", allLower);
    }

  • All - Grouped

    public void Linq72() {
       List products = GetProductList();
       var productGroups =
          from p in products
          group p by p.Category into g
          where g.Group.All(p => p.UnitsInStock > 0)
          select new {Category = g.Key, Products = g.Group};
       ObjectDumper.Write(productGroups, 1);
    }

Aggregate Operators
  • Count - Simple

    public void Linq73() {
       int[] factorsOf300 = { 2, 2, 3, 5, 5 };
       int uniqueFactors = factorsOf300.Distinct().Count();
       Console.WriteLine("There are {0} unique factors of 300.", uniqueFactors);
    }

  • Count - Conditional

    public void Linq74() {
       int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
       int oddNumbers = numbers.Count(n => n % 2 == 1);
       Console.WriteLine("There are {0} odd numbers in the list.", oddNumbers);
    }

  • Count - Indexed

    public void Linq75() {
       int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
       int oddEvenMatches = numbers.Count((n, index) => n % 2 == index % 2);
       Console.WriteLine("There are {0} numbers in the list whose odd/even status " +
            "matches that of their position.", oddEvenMatches);
    }

  • Count - Nested

    public void Linq76() {
       List customers = GetCustomerList();
       var orderCounts =
          from c in customers
          select new {c.CustomerID, OrderCount = c.Orders.Count()};
       ObjectDumper.Write(orderCounts);
    }

  • Count - Grouped

    public void Linq77() {
       List products = GetProductList();
       var categoryCounts =
          from p in products
          group p by p.Category into g
          select new {Category = g.Key, ProductCount = g.Group.Count()};
       ObjectDumper.Write(categoryCounts);
    }

  • Sum - Simple

    public void Linq78() {
       int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
       double numSum = numbers.Sum();
       Console.WriteLine("The sum of the numbers is {0}.", numSum);
    }

  • Sum - Projection

    public void Linq79() {
       string[] words = { "cherry", "apple", "blueberry" };
       double totalChars = words.Sum(w => w.Length);
       Console.WriteLine("There are a total of {0} characters in these words.", totalChars);
    }

  • Sum - Grouped

    public void Linq80() {
       List products = GetProductList();
       var categories =
          from p in products
          group p by p.Category into g
          select new {Category = g.Key, TotalUnitsInStock = g.Group.Sum(p => p.UnitsInStock)};
       ObjectDumper.Write(categories);
    }

  • Min - Simple

    public void Linq81() {
       int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
       int minNum = numbers.Min();
       Console.WriteLine("The minimum number is {0}.", minNum);
    }

  • Min - Projection

    public void Linq82() {
       string[] words = { "cherry", "apple", "blueberry" };
       int shortestWord = words.Min(w => w.Length);
       Console.WriteLine("The shortest word is {0} characters long.", shortestWord);
    }

  • Min - Grouped

    public void Linq83() {
       List products = GetProductList();
       var categories =
          from p in products
          group p by p.Category into g
          select new {Category = g.Key, CheapestPrice = g.Group.Min(p => p.UnitPrice)};
       ObjectDumper.Write(categories);
    }

  • Min - Elements

    public void Linq84() {
       List products = GetProductList();
       var categories =
          from p in products
          group p by p.Category into g
          from minPrice = g.Group.Min(p => p.UnitPrice)
          select new {Category = g.Key, CheapestProducts = g.Group.Where(p => p.UnitPrice == minPrice)};
       ObjectDumper.Write(categories, 1);
    }

  • Max - Simple

    public void Linq85() {
       int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
       int maxNum = numbers.Max();
       Console.WriteLine("The maximum number is {0}.", maxNum);
    }

  • Max - Projection

    public void Linq86() {
       string[] words = { "cherry", "apple", "blueberry" };
       int longestLength = words.Max(w => w.Length);
       Console.WriteLine("The longest word is {0} characters long.", longestLength);
    }

  • Max - Grouped

    public void Linq87() {
       List products = GetProductList();
       var categories =
          from p in products
          group p by p.Category into g
          select new {Category = g.Key, MostExpensivePrice = g.Group.Max(p => p.UnitPrice)};
       ObjectDumper.Write(categories);
    }

  • Max - Elements

    public void Linq88() {
       List products = GetProductList();
       var categories =
          from p in products
          group p by p.Category into g
          from maxPrice = g.Group.Max(p => p.UnitPrice)
          select new {Category = g.Key, MostExpensiveProducts = g.Group.Where(p => p.UnitPrice == maxPrice)};
       ObjectDumper.Write(categories, 1);
    }

  • Average - Simple

    public void Linq89() {
       int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
       double averageNum = numbers.Average();
       Console.WriteLine("The average number is {0}.", averageNum);
    }

  • Average - Projection

    public void Linq90() {
       string[] words = { "cherry", "apple", "blueberry" };
       double averageLength = words.Average(w => w.Length);
       Console.WriteLine("The average word length is {0} characters.", averageLength);
    }

  • Average - Grouped

    public void Linq91() {
       List products = GetProductList();
       var categories =
          from p in products
          group p by p.Category into g
          select new {Category = g.Key, AveragePrice = g.Group.Average(p => p.UnitPrice)};
       ObjectDumper.Write(categories);
    }

  • Fold - Simple

    public void Linq92() {
       double[] doubles = { 1.7, 2.3, 1.9, 4.1, 2.9 };
       double product = doubles.Fold((runningProduct, nextFactor) => runningProduct * nextFactor);
       Console.WriteLine("Total product of all numbers: {0}", product);
    }

  • Fold - Seed

    public void Linq93() {
       double startBalance = 100.0;
       int[] attemptedWithdrawals = { 20, 10, 40, 50, 10, 70, 30 };
       double endBalance =
          attemptedWithdrawals.Fold(startBalance,
             (balance, nextWithdrawal) =>
                ( (nextWithdrawal <= balance) ? (balance - nextWithdrawal) : balance ) );
       Console.WriteLine("Ending balance: {0}", endBalance);
    }

Miscellaneous Operators
  • Concat - 1

    public void Linq94() {
        int[] numbersA = { 0, 2, 4, 5, 6, 8, 9 };
        int[] numbersB = { 1, 3, 5, 7, 8 };
        var allNumbers = numbersA.Concat(numbersB);
        Console.WriteLine("All numbers from both arrays:");
        foreach (var n in allNumbers) {
            Console.WriteLine(n);
        }
    }

  • Concat - 2

    public void Linq95() {
        List customers = GetCustomerList();
        List products = GetProductList();
        var customerNames =
            from c in customers
            select c.CompanyName;
        var productNames =
            from p in products
            select p.ProductName;
        var allNames = customerNames.Concat(productNames);
        Console.WriteLine("Customer and product names:");
        foreach (var n in allNames) {
            Console.WriteLine(n);
        }
    }

  • EqualAll - 1

    public void Linq96() {
        var wordsA = new string[] { "cherry", "apple", "blueberry" };
        var wordsB = new string[] { "cherry", "apple", "blueberry" };
        bool match = wordsA.EqualAll(wordsB);
        Console.WriteLine("The sequences match: {0}", match);
    }

  • EqualAll - 2

    public void Linq97() {
        var wordsA = new string[] { "cherry", "apple", "blueberry" };
        var wordsB = new string[] { "apple", "blueberry", "cherry" };
        bool match = wordsA.EqualAll(wordsB);
        Console.WriteLine("The sequences match: {0}", match);
    }

Custom Sequence Operators
  • Combine

    public static class CustomSequenceOperators
    {
        public static IEnumerable Combine(this IEnumerable first, IEnumerable second, Func func) {
            using (IEnumerator e1 = first.GetEnumerator(), e2 = second.GetEnumerator()) {
                while (e1.MoveNext() && e2.MoveNext()) {
                    yield return func(e1.Current, e2.Current);
                }
            }
        }
    }
    public void Linq98() {           
        int[] vectorA = { 0, 2, 4, 5, 6 };
        int[] vectorB = { 1, 3, 5, 7, 8 };
        int dotProduct = vectorA.Combine(vectorB, (a, b) => a * b).Sum();
        Console.WriteLine("Dot product: {0}", dotProduct);
    }

Query Execution
  • Deferred

    public void Linq99() {
        // Sequence operators form first-class queries that
        // are not executed until you enumerate over them.
        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;
        // Note, the local variable 'i' is not incremented
        // until each element is evaluated (as a side-effect):
        foreach (var v in q) {
            Console.WriteLine("v = {0}, i = {1}", v, i);        
        }
    }

  • Immediate

    public void Linq100() {
        // Methods like ToList() cause the query to be
        // executed immediately, caching the results.
        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);
        }
    }

  • Query Reuse

    public void Linq101() {
        // Deferred execution lets us define a query once
        // and then reuse it later after data changes.
        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];
        }
        // During this second run, the same query object,
        // lowNumbers, will be iterating over the new state
        // of numbers[], producing different results:
        Console.WriteLine("Second run numbers <= 3:");
        foreach (int n in lowNumbers) {
            Console.WriteLine(n);
        }
    }