Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why are IEnumerable Projections not Immutable?

Tags:

c#

linq

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.

like image 222
Oskar Lindberg Avatar asked Jun 02 '15 15:06

Oskar Lindberg


People also ask

Is IEnumerable immutable?

Just realized IEnumerable is immutable, what are other commonly used immutable generic interfaces?

Is IEnumerable readonly?

IEnumerable<T> is always readonly, by definition. However, the objects inside may be mutable, as in this case.

What is immutable List in c#?

Represents an immutable list, which is a strongly typed list of objects that can be accessed by index.

What is IEnumerable string in c#?

IEnumerable in C# is an interface that defines one method, GetEnumerator which returns an IEnumerator interface. This allows readonly access to a collection then a collection that implements IEnumerable can be used with a for-each statement.


Video Answer


1 Answers

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.

like image 83
Jon Skeet Avatar answered Oct 01 '22 23:10

Jon Skeet