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.
Just realized IEnumerable is immutable, what are other commonly used immutable generic interfaces?
IEnumerable<T> is always readonly, by definition. However, the objects inside may be mutable, as in this case.
Represents an immutable list, which is a strongly typed list of objects that can be accessed by index.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With