Just because a method returns IEnumerable doesn't mean there will be deferred execution.
E.g.
IEnumerable<string> GetNames()
{
Console.WriteLine("Yolo");
return new string[] { "Fred", "Wilma", "Betty", "Barney" };
}
var names = GetNames(); // Yolo prints out here! and only here!
foreach(name in names)
{
// Some code...
}
foreach(name in names)
{
// Some code...
}
Back to the question, if:
a. There is deferred execution (e.g. LINQ - .Where(), .Select(), etc.): then the method returns a "promise" that knows how to iterate over the collection. So when calling .ToList() this iteration happens and we store the list in memory.
b. There is no deferred execution (e.g. method returns a List): then assuming GetNames returns a list, it's basically like doing a .ToList() on that list
var names = GetNames().ToList();
// 1 2 3
- Yolo Prints out
- List is returned
- ReturnedList.ToList() is called
PS, I left the following comment on Resharper's documentation
Hi,
Can you please make it clear in the documentation that this'd only be
an issue if GetNames() implements deferred execution?
For example, if GetNames() uses yield under the hood or implements a
deferred execution approach like most LINQ statements for example
(.Select(), .Where(), etc.)
Otherwise, if under the hood GetNames() is not returning an
IEnumerable that implements defered execution, then there is no
performance or data integrity issues here. E.g. if GetNames returns
List