static void TestQuerySyntax()
        {
            List <int> numbers = new List <int> {
                2, 4, 8, 16, 32
            };

            IEnumerable <int> evenNumbers = (from number in numbers
                                             where number > 10
                                             select number);

            // collection of objects
            var birds = new SimpleBirdRepository().GetBirds();

            // query projection - use anonymous type for the result
            var redBirdds = from b in birds
                            where b.Color.Equals("Red", StringComparison.OrdinalIgnoreCase) && b.Sightings > 2
                            select new { BirdName = b.Name, b.Sightings };

            // create object of anonymous type; IMPORTANT: properties are R/O!
            var anonymousPidgeon = new { Name = "Pidgeon", Color = "White", Sightings = 10 };

            var canary = new SimpleBird {
                Name = "Canary", Color = "Yellow", Sightings = 0
            };

            birds.Add(canary);

            var matchingBirds = from b in birds
                                where b.Color != anonymousPidgeon.Color
                                orderby b.Name descending, b.Color
                select new { BirdName = b.Name };

            // grouping; use "into" to include grouping result in a "where" clause
            var birdCol = from b in birds
                          group b by b.Color
                          into birdsByColor
                          where birdsByColor.Count() > 1
                          select new { Color = birdsByColor.Key, Count = birdsByColor.Count() };
        }
        static void TestMethodSyntax()
        {
            var birds = new SimpleBirdRepository().GetBirds();

            // use method syntax instead of query syntax
            var redBirds = birds
                           .Where(b => b.Color.Equals("red", StringComparison.OrdinalIgnoreCase))
                           .OrderBy(b => b.Name)
                           .ThenByDescending(b => b.Sightings)
                           .Select(b => new { BirdName = b.Name, b.Sightings });

            // quantifiers: Any(), All()
            // take elements: First[OrDefault](), Single[OrDefault](), Last[OrDefault](), ElementAt[OrDefault]()


            // partitioning operators: Skip(), Take(), SkipWhile(), TakeWhile()
            var birdsWithLongName = birds
                                    .OrderBy(b => b.Name.Length)
                                    .SkipWhile(b => b.Name.Length < 6);


            // join operators: Join(), GroupJoin()
            var colors = new List <string> {
                "Red", "White", "Purple"
            };
            // use query syntax
            var favColorBirds = from b in birds
                                join c in colors on b.Color equals c
                                select b;
            // use method syntax
            var theSameBirds = birds.Join(colors, b => b.Color, c => c, (b, c) => b);

            var groupedBirds = colors.GroupJoin(
                birds,
                c => c,
                b => b.Color,
                (c, b) => new { Color = c, Birds = b });

            var allGroupedBirds = groupedBirds.SelectMany(g => g.Birds);


            // aggregations: Count(), Sum(), Average(), Min(), Max()
            var birdCountByColor = birds
                                   .GroupBy(b => b.Color)
                                   .Select(g => new { Color = g.Key, Count = g.Count(), Sightings = g.Sum(b => b.Sightings) }); // note the use of property "Key" - the grouping field


            // set operators: Distinct(), Except(), Union(), Intersect(), Concat()
            birds.Add(new SimpleBird {
                Name = "Pelican", Color = "Pink", Sightings = 6
            });
            var birdColors       = birds.Select(b => b.Color).Distinct(); // remove duplicates
            var colorWithNoBirds = colors.Except(birds.Select(b => b.Color).Distinct());
            var allColors        = colors.Union(birds.Select(b => b.Color).Distinct());
            var matchingColors   = colors.Intersect(birds.Select(b => b.Color).Distinct());
            var combinedColors   = colors.Concat(birds.Select(b => b.Color).Distinct()); // does not remove duplicates in the sets


            // generation operators: Range(), Repeat(), Empty(), DefaultIfEmpty()
            var numbers    = Enumerable.Range(0, 10);
            var blankBirds = Enumerable.Repeat(new SimpleBird(), 5);
            var emptyBirds = Enumerable.Empty <SimpleBird>();
            var emptyBird  = emptyBirds.DefaultIfEmpty(); // returns null

            // conversion operators: ToList(), ToArray(), AsEnumerable(), ToDictionary(), ...
        }