Foreach in Select and List

Asked

Viewed 2,049 times

1

I recently discovered that there’s a big difference between doing some operations, like Select and Where, in Queryable and listed objects such as Enumerable and List. In this and in this question.

Knowing this, I was curious to know if there are differences between iterating values of a List and iterate values directly from a Select.
I saw in the debug that when I just do Select I’m iterating on a {System.Linq.Enumerable.WhereSelectListIterator<string, string>}.

When I do Where or Select in a list the operation is executed at the time the method is called or is only executed when I access the items or use ToList()?

In addition, there is some difference in performance between the two cases?
It’s easier to iterate on a List or it is more costly to transform into List and then iterate?

Other than that:

var lista = new List<string>() { ... };
var listaFiltrada = lista.Select(x => x).ToList();

foreach (var item in listaFiltrada) { ... }

For that reason:

var lista = new List<string>() { ... };
var selectFiltrado = lista.Select(x => x);

foreach (var item in selectFiltrado) { ... }

1 answer

1


When I do Where or Select in a list the operation is executed at the time the method is called or is only executed when I access the items or use ToList()?

Whereas LINQ to SQL or Entity Framework, only at the time of conversion to IEnumerable, that is to say, ToList().

What Select generates an iterator that will serve as a filter in the next operation, such as ToList(), for example. In the case of IQueryable, this filter of Select will be interpreted as the columns of a selection in SQL. For example:

var listaExemplo = context.Entidades.Select(x => new { x.Coluna1, x.Coluna2, x.Coluna3 }).ToList();

An SQL will be generated like this:

SELECT COLUNA1, COLUNA2, COLUNA3 FROM ENTIDADES

For objects in memory, Select returns this special object (WhereSelectListIterator<string, string>). He’s an iterator, just like GetEnumerator also returns an iterator.

Here:

var listaFiltrada = lista.Select(x => x).ToList();

foreach (var item in listaFiltrada) { ... }

You solve the enumeration and pass to the foreach a materialized list, while here:

var selectFiltrado = lista.Select(x => x);

foreach (var item in selectFiltrado) { ... }

You indicate that selectFiltrado will be an enumerator (iterator) whose resolution will transform each enumeration object into the inside predicate of Select (in the example, return the object itself without change). The list therefore does not materialize.

The first example is useful when:

  • You need to get something from the list as a list before the foreach;
  • You need to solve a query SQL and only then manipulate the result.

The second example is useful when:

  • The list does not need to be materialized before the foreach.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.