Chaining Standard Query Operators Together

This is the final topic in the Chaining Queries Together tutorial.

The standard query operators can also be chained together. For example, you can interject the Enumerable.Where operator, and it also operates in a lazy fashion. No intermediate results are materialized by it.

Example

In this example, the Where method is called before calling ConvertCollectionToUpperCase. The Where method operates in almost exactly the same way as the lazy methods used in previous examples in this tutorial, ConvertCollectionToUpperCase and AppendString.

One difference is that in this case, the Where method iterates through its source collection, determines that the first item does not pass the predicate, and then gets the next item, which does pass. It then yields the second item.

However, the basic idea is the same: Intermediate collections are not materialized unless they have to be.

When query expressions are used, they are converted to calls to the standard query operators, and the same principles apply.

All of the examples in this section that are querying Office Open XML documents use the same principle. Deferred execution and lazy evaluation are some of the fundamental concepts that you must understand to use LINQ (and LINQ to XML) effectively.

Note

The following example uses the yield return construct of C#. Because there is no equivalent feature in Visual Basic 2008, this example is provided only in C#.

public static class LocalExtensions
{
    public static IEnumerable<string>
      ConvertCollectionToUpperCase(this IEnumerable<string> source)
    {
        foreach (string str in source)
        {
            Console.WriteLine("ToUpper: source >{0}<", str);
            yield return str.ToUpper();
        }
    }

    public static IEnumerable<string>
      AppendString(this IEnumerable<string> source, string stringToAppend)
    {
        foreach (string str in source)
        {
            Console.WriteLine("AppendString: source >{0}<", str);
            yield return str + stringToAppend;
        }
    }
}

class Program
{
    static void Main(string[] args)
    {
        string[] stringArray = { "abc", "def", "ghi" };

        IEnumerable<string> q1 =
            from s in stringArray.ConvertCollectionToUpperCase()
            where s.CompareTo("D") >= 0
            select s;

        IEnumerable<string> q2 =
            from s in q1.AppendString("!!!")
            select s;

        foreach (string str in q2)
        {
            Console.WriteLine("Main: str >{0}<", str);
            Console.WriteLine();
        }
    }
}

This example produces the following output:

ToUpper: source >abc<
ToUpper: source >def<
AppendString: source >DEF<
Main: str >DEF!!!<

ToUpper: source >ghi<
AppendString: source >GHI<
Main: str >GHI!!!<

See Also

Concepts

Tutorial: Chaining Queries Together