Skip to main content
added 1 character in body
Source Link
Gert Arnold
  • 2.1k
  • 1
  • 17
  • 26

This is generally considered to be a bad idea. IEnumerable has deferred execution, which means that in your example, someList can be forced to enumerate any desired number of times.

As a consequence, it depends on the implementation behind the IEnumerable whether any changes applied by action will still be visible after your methods have run. There are two possibilities:

  1. someList is a materialized list (for example, List<SomeObject>). After running ForEachAction, a new enumeration of someList will produce the same, modified, objects.
  2. someList is an enumerable that produces new objects on each execution. After running ForEachAction, a new enumeration of someList will produce new objects. The changed objects are out of scope and will soon be garbage collected.

An example of the second option is an IQueryable against a SQL backend. When it is executed it will emit a SQL query that returns new objects from the database (caching as applied by many ORMs aside).

In that case it totally depends on what happens in action whether any effect of it is persistent. If action only modifies objects in someList its effect will be lost. If it uses objects in someList to change some external state (e.g. increment some sum value) its effect will persist.

As a conclusion, I wouldn't do this. If you want to apply void methods to any IEnumerable, first materialize it to a list and then apply existing methods. Instead of...

someList.ForEachAction(x => x.Update());

...you'd have...

var concreteList = someList.ToList();
concreteList.ForEach(x => x.Update());

Now continue working with concreteList so you'll be sure that the effect of x.Update() will remain visible in your code.

This is generally considered to be a bad idea. IEnumerable has deferred execution, which means that in your example, someList can be forced to enumerate any desired number of times.

As a consequence, it depends on the implementation behind the IEnumerable whether any changes applied by action will still be visible after your methods have run. There are two possibilities:

  1. someList is a materialized list (for example, List<SomeObject>). After running ForEachAction, a new enumeration of someList will produce the same, modified, objects.
  2. someList is an enumerable that produces new objects on each execution. After running ForEachAction, a new enumeration of someList will produce new objects. The changed objects are out of scope and will soon be garbage collected.

An example of the second option is an IQueryable against a SQL backend. When it is executed it will emit a SQL query that returns new objects from the database (caching as applied by many ORMs aside).

In that case it totally depends on what happens in action whether any effect of it is persistent. If action only modifies objects in someList its effect will be lost. If it uses objects in someList to change some external state (e.g. increment some sum value) its effect will persist.

As a conclusion, I wouldn't do this. If you want to apply void methods to any IEnumerable, first materialize it to a list and then apply existing methods. Instead of...

someList.ForEachAction(x => x.Update());

...you'd have...

var concreteList = someList.ToList()
concreteList.ForEach(x => x.Update());

Now continue working with concreteList so you'll be sure that the effect of x.Update() will remain visible in your code.

This is generally considered to be a bad idea. IEnumerable has deferred execution, which means that in your example, someList can be forced to enumerate any desired number of times.

As a consequence, it depends on the implementation behind the IEnumerable whether any changes applied by action will still be visible after your methods have run. There are two possibilities:

  1. someList is a materialized list (for example, List<SomeObject>). After running ForEachAction, a new enumeration of someList will produce the same, modified, objects.
  2. someList is an enumerable that produces new objects on each execution. After running ForEachAction, a new enumeration of someList will produce new objects. The changed objects are out of scope and will soon be garbage collected.

An example of the second option is an IQueryable against a SQL backend. When it is executed it will emit a SQL query that returns new objects from the database (caching as applied by many ORMs aside).

In that case it totally depends on what happens in action whether any effect of it is persistent. If action only modifies objects in someList its effect will be lost. If it uses objects in someList to change some external state (e.g. increment some sum value) its effect will persist.

As a conclusion, I wouldn't do this. If you want to apply void methods to any IEnumerable, first materialize it to a list and then apply existing methods. Instead of...

someList.ForEachAction(x => x.Update());

...you'd have...

var concreteList = someList.ToList();
concreteList.ForEach(x => x.Update());

Now continue working with concreteList so you'll be sure that the effect of x.Update() will remain visible in your code.

Source Link
Gert Arnold
  • 2.1k
  • 1
  • 17
  • 26

This is generally considered to be a bad idea. IEnumerable has deferred execution, which means that in your example, someList can be forced to enumerate any desired number of times.

As a consequence, it depends on the implementation behind the IEnumerable whether any changes applied by action will still be visible after your methods have run. There are two possibilities:

  1. someList is a materialized list (for example, List<SomeObject>). After running ForEachAction, a new enumeration of someList will produce the same, modified, objects.
  2. someList is an enumerable that produces new objects on each execution. After running ForEachAction, a new enumeration of someList will produce new objects. The changed objects are out of scope and will soon be garbage collected.

An example of the second option is an IQueryable against a SQL backend. When it is executed it will emit a SQL query that returns new objects from the database (caching as applied by many ORMs aside).

In that case it totally depends on what happens in action whether any effect of it is persistent. If action only modifies objects in someList its effect will be lost. If it uses objects in someList to change some external state (e.g. increment some sum value) its effect will persist.

As a conclusion, I wouldn't do this. If you want to apply void methods to any IEnumerable, first materialize it to a list and then apply existing methods. Instead of...

someList.ForEachAction(x => x.Update());

...you'd have...

var concreteList = someList.ToList()
concreteList.ForEach(x => x.Update());

Now continue working with concreteList so you'll be sure that the effect of x.Update() will remain visible in your code.