LINQ & IEnumerable<String> Re-evaluation

淺唱寂寞╮ 提交于 2021-01-28 19:27:25

问题


Good morning,

I wrote the following LINQ query

 public static Func<String, IEnumerable<String>> ListaCorreccoes = (StrPalavra) =>
    {

        return (from StrTmp in ListaPossiveisCorreccoes(StrPalavra)
                from StrTmp2 in ListaPossiveisCorreccoes(StrTmp)
                where PalavraConhecida(StrTmp2)
                select StrTmp2).Distinct();            

    };

which, to my surprise, is much faster than using two foreach cicles. After running this function using ListaTmp = ListaCorreccoes("comutador");, where ListaTmp is of type IEnumerable<String>, I need to print ListaTmp's cardinality using

        Console.Write(">> Prima qualquer tecla para listar todas as " + ListaTmp.Count() + " correcções...");

and to print the contents of ListaTmp, using

foreach (String StrTmp in ListaTmp)
            Console.WriteLine(StrTmp);

However, both the last and prior-to-last lines of code cause ListaTmp and thus the query to be re-evaluated, which is so very strange since the variable is being assigned the result of the query. Why has this code such a strange behaviour?

Thank you very much.


回答1:


That's because LINQ uses deferred execution. See Charlie Calvert's article on LINQ and Deferred Execution.

Try this instead:

var ListaTmp = ListaCorreccoes("comutador").ToList();

This enumerates once and stores the result in a List<string>.

You might find Jon Skeet's articles useful:

  • Iterators, iterator blocks and data pipelines
  • Iterator block implementation details: auto-generated state machines



回答2:


This is because ListaTmp is not a result set, but a query. Specifically for the Count, you're actually creating a new query (you expend the Linq expression) which you then execute.

The real type of ListaTmp is not IEnumerable, but IQueryable, which is a Linq query.



来源:https://stackoverflow.com/questions/3976113/linq-ienumerablestring-re-evaluation

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!