I can't decide whether my method that returns an IEnumerable<T>
should itself be lazy or whether it should build a list and return that. I often opt for the latter so I can be sure the enumeration of each value isn't performed multiple times.
For example:
public IEnumerable<UserProfile> GetUsers()
{
var allDepartments = GetAllDepartments(active: true); // Returns IEnumerable<Department>
var allUsers = GetAllUserDepartments(active: true); // Returns IEnumerable<User>
var users
= allDepartments
.Join(allUsers, x => x.Department, y => y.Department, (x, y) => y, StringComparer.OrdinalIgnoreCase)
.Distinct()
.Select(x => GetUserProfile(x))
.ToList(); // Is this recommended or not
return users;
}
The key part is each enumeration is doing something (GetUserProfile
) non trivial, it might be expensive, it might not, but what's the recommendation for a method that returns an IEnumerable<T>
? Should it care about whether the caller might enumerate it several times or not?
Assume only IEnumerable<T>
functionality is required by the caller and my question can be reworded into:
How do I signify to the caller that each enumeration may be expensive?
How expensive it is, may change their implementation decisions. If they enumerate the whole lot several times, then a ToList()
makes sense to them to perform. If they don't enumerate the whole lot, then a ToList()
would be a waste for me (or the caller) to perform.
IList
andICollection
are both mutable contracts.IEnumerable
has the dual purpose of having lazy-evaluation semantics but also being a immutable structure to users. \$\endgroup\$