Why are IEnumerable Projections not Immutable?

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

(.NET Fiddle here)

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.

Jon Skeet
people
quotationmark

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.

people

See more on this question at Stackoverflow