IsReadOnly forbids you to internally modify a custom IList?

Note for IList.IsReadOnly specify the following:

A read-only collection does not allow you to add, delete, or modify items after the collection is created.

Does this mean that a user class that implements IList cannot add or remove elements within itself, or simply prohibits users from doing this using the mothods interfaces?

If internal modifications are allowed, does this mean that code that expects IList with IsReadOnly true to never change is inherently broken?

If internal modifications are not allowed, does this mean that it is impossible to write a valid IList that can change internally, but does not allow users to change it?

+7
c #
source share
3 answers

https://msdn.microsoft.com/en-us/library/cc645181%28v=vs.110%29.aspx

A read-only collection is simply a collection with a wrapper that prevents the collection from being modified; therefore, if changes are made to the base collection, the read-only collection reflects these changes.

For another type, you don’t have to stop exposing a truly immutable collection as IList<T> when this property returns true, but you don’t need to.

We also see that cases from the frame library that return true for IsReadOnly often allow mutations in the internal collection.

 List<int> initialList = new List<int> { 1 }; IList<int> readOnly = new ReadOnlyCollection<int>(initialList); Console.WriteLine(readOnly.Count); // 1 Console.WriteLine(readOnly.IsReadOnly); // True initialList.Add(2); Console.WriteLine(readOnly.Count); // 2 

Indeed, IsReadOnly tells you that mutating methods such as Add and the setter side of the indexer will fail, and not that the object is immutable by all means.

An interesting consideration in this regard: some places within the library libraries themselves need read-only lists that are truly readable. Their public interface returns either ReadOnlyCollection<T> or IReadOnlyList<T> (for example, BlockExpression.Expressions returns ReadOnlyCollection<T> ), but they do not trust the read-only collections passed to them. They use an internal type called TrueReadOnlyCollection<T> , which is created as a wrapper of a new array, copied by construction, so nothing else can change it. This type hopes that it will never change and therefore can be used for sharing, but all other cases are not.

+5
source share

Internal code can really change it.

IsReadOnly indicates that the list cannot be directly modified through this interface.

I agree that "code that expects IList with IsReadOnly true to never change is inherently broken."

Microsoft has implemented the ImmutableList<T> class, and perhaps this is one of the reasons.

IReadOnlyList to the rescue? Er, unfortunately not:

 List<int> test = new List<int> {1}; IReadOnlyList<int> readOnly = test; // Because List<T> implements IReadOnlyList<int>. Console.WriteLine(readOnly[0]); // Prints 1. test[0] = 2; Console.WriteLine(readOnly[0]); // Prints 2. Oops. 

For these reasons, that some time ago I suggested not declaring interfaces for immutable types .

And here is another example using List<T>.AsReadOnly() . This demonstrates that you can mutate the list using IReadOnly set true using only the built-in .Net types:

 Console.WriteLine(shouldBeReadOnly.IsReadOnly); // Readonly? Yep! This prints True. Console.WriteLine(shouldBeReadOnly[0]); // Prints 1. Console.WriteLine(shouldBeReadOnly.Count); // Prints 1. test[0] = 2; test.Add(-1); Console.WriteLine(shouldBeReadOnly[0]); // Prints 2. Oops. It wasn't readonly at all. Console.WriteLine(shouldBeReadOnly.Count); // Prints 2. 

Please note that you can change the number of elements as well as the elements themselves.

+4
source share

A class that implements IList with IsReadOnly==true promises, which after its creation does not change, both inside and outside. Of course, the developer must fulfill this promise. If it fails, then the IList implementation will be violated, not the code that uses it.

It can be argued that this should only be done to explicitly implement the interface. I would still consider such an implementation violated.

+1
source share

All Articles