Assuming my Awesome
class has a property Bazinga
, which is a String
with the default value of "Default value", I could go:
var enumerableOfAwesome = Enumerable
.Range(1, 5)
.Select(n => new Awesome());
foreach (var a in enumerableOfAwesome)
a.Bazinga = "New value";
As you may already be aware, enumerating the enumerableOfAwesome
again will not make you happy, if you expect to find your "New value" strings safely tucked away in all the Bazinga
. Instead, outputting them to the console would render:
Default value
Default value
Default value
Default value
Default value
This is all well and dandy from some deferred execution point-of-view, and that issue has been discussed already before, like here and here. My question however is why the enumerator implementations do not return immutable objects; If persistence over several enumerations is not guaranteed, then what use is there of the ability to set values, save making people confused?
Maybe this isn't a very good question, but I'm sure your answers will be enlightening.
My question however is why the enumerator implementations do not return immutable objects
How would you expect them to do that? They're sequences of whatever type is used - what would you expect to happen with something like:
var builders = new string[] { "foo", "bar" }.Select(x => new StringBuilder(x));
? Would you expect it (whatever "it" is in this case) to create a new type automatically with the same API as StringBuilder
, but magically making it immutable? How would it detect mutations?
Basically, what you're asking for is infeasible - you can have a sequence where the element type is mutable, so while iterating through it you can mutate the object that the yielded reference refers to. Expecting anything else is unrealistic, IMO.
See more on this question at Stackoverflow