Exemplo de consultas em cadeia (C#) (LINQ to XML)
Este exemplo baseia-se no exemplo em Exemplo de execução adiada e mostra o que acontece quando você encadeia duas consultas que usam execução adiada e avaliação lenta.
Exemplo: Adicionar um segundo método de extensão que usa yield return
para adiar a execução
Neste exemplo, outro método de extensão é introduzido, AppendString
, que acrescenta uma cadeia de caracteres especificada em cada cadeia de caracteres na coleção de origem e, em seguida, produz a cadeia de caracteres alterada.
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()
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();
}
}
}
Este exemplo produz a seguinte saída:
ToUpper: source >abc<
AppendString: source >ABC<
Main: str >ABC!!!<
ToUpper: source >def<
AppendString: source >DEF<
Main: str >DEF!!!<
ToUpper: source >ghi<
AppendString: source >GHI<
Main: str >GHI!!!<
Neste exemplo, você pode ver que cada método de extensão opera um de cada vez para cada item na coleção de origem.
O que deve ficar claro a partir deste exemplo é que, embora tenhamos encadeado consultas que produzem coleções, nenhuma coleção intermediária é materializada. Em vez disso, cada item é passado de um método preguiçoso para o próximo. Isso resulta em uma pegada de memória muito menor do que uma abordagem que primeiro pegaria uma matriz de strings, depois criaria uma segunda matriz de strings que foram convertidas em maiúsculas e, finalmente, criaria uma terceira matriz de strings onde cada string tem os pontos de exclamação anexados a ela.
O próximo artigo deste tutorial ilustra a materialização intermediária: