0

Is there any class in .net which works like IReadOnlyList but it holds internal copy of all items? If something returns IReadOnlyList, there is no guarantee that underlying collection will no be modified?...

EDIT:

From documentation:

An instance of the ReadOnlyCollection<T> generic class is always read-only. A collection that is read-only is simply a collection with a wrapper that prevents modifying the collection; therefore, if changes are made to the underlying collection, the read-only collection == reflects == those changes

So it's not true read only.

EDIT2:

I need something like read-only array.

For example:

public class ReadOnlyArray<T> : IEnumerable<T>, ...
{
    public ReadOnlyArray (IEnumerable<T> items)
    {
          internalItems = createCopy (items);
    }
}

now when I see code like this: ReadOnlyArray x = GetDataFrom3rdAPI();

I'm 100% I am not only receiving read-only object, but also it is not possible to modify underlying collection somewhere else in code. The class type should say it gives me that comfort.

With ReadOnlyCollection, it says only I can read, but I have no control over underyling collection - I dont know is there any reference to underlying collection in other places in 3rd API code.

EDIT3:

When I said underlying collection should not be modified, I had on my mind that all items in collection (all references) should always point to the same instance. However those instances itself can be mutable.

So when Im iterating through this collection, I'm always iterating the same instances.

apocalypse
  • 5,764
  • 9
  • 47
  • 95
  • https://msdn.microsoft.com/en-us/library/ms132474(v=vs.110).aspx – Dmitry Bychenko Nov 09 '15 at 14:23
  • Possible duplicate of [Return collection as read-only](http://stackoverflow.com/questions/55502/return-collection-as-read-only) – Almo Nov 09 '15 at 14:26
  • @zgnilec Have you encountered the immutable collections? – Adam Houldsworth Nov 09 '15 at 14:51
  • @AdamHouldsworth: what? I need to explicitly know the underylying collection cannot be changed. So I think I need to create class for my own. – apocalypse Nov 09 '15 at 14:57
  • How about an Array? Its seems like you do not want to Add,Remove or else. Its the nearest thing to an True ReadOnlyList you have in .net. You can query against it and access its internal items but you cannot modfy the array itself without changeing the instance. – Venson Nov 09 '15 at 14:58
  • 1
    @zgnilec The Immutable Collections are, by definition, immutable. They have been created from the ground up, so far as I can remember, to take advantage of immutability. They will convey the correct intent. – Adam Houldsworth Nov 09 '15 at 14:59
  • @JPVenson: an `Array` is just about as far removed from an immutable data structure as you can get. The *only* thing that's immutable about an array is its size. – Gary McGill Nov 09 '15 at 16:14
  • @zgnilec: It depends what you want to be immutable. You could create a list that you can't add items to, or remove items from, but if the items themselves are mutable (e.g. you have a list of `Customer` objects), then you've still got the ability to modify "the content of the list". Yes you can take a copy of each `Customer`, but what if `Customer` has references to `Order`s? You'd need a deep copy - and sooner or later,you might have a reference to something too big to copy. – Gary McGill Nov 09 '15 at 16:18
  • @GaryMcGill but isn't he asking for exactly that? He want a collection that cannot be modified by its Instance. How to you add items to an array? would be interesting to know. We need more clarification what the OP means by "Not Modified". I Guess he has given a Collection from code he cannot change. This collection must be set to "ReadOnly". So the Only sollution would be an Enumeration to an Array to save the "current" state. – Venson Nov 10 '15 at 09:12
  • @JPVenson: perhaps I misunderstand the question, but I think OP wants a collection where, if it initially contains A, B and C, then it will *always* contain A, B and C. Using an array would only guarantee that it always had 3 elements - but you (or any other code with access to the array) could change those elements to X, Y and Z. – Gary McGill Nov 10 '15 at 10:07
  • @GaryMcGill You are right. You could change the elements inside the array, but i understood it that the OP asks how to prevent the source collection to be changed from outside. He has a collection that he tries to set to readonly more or less. Fmpov this is not Possible. By trying to wrapping it inside a ReadOnlyCollection (thats the main point why i guess what i guess) he tries to set the source to readonly which is not possible. To ensure that the Collection he got will not change from outside, he has to copy the collection ( and maybe then wrap it with ReadOnlyCollection) – Venson Nov 10 '15 at 14:57

3 Answers3

3

Given any IEnumerable<T> foo, use foo.ToList().AsReadOnly(). This will make a new List<T> containing the elements of foo, even if was already a list, and then make a read-only wrapper around that list. As the underlying collection for the ReadOnlyCollection<T> is the one you just created, nothing else will have a reference to it and so nothing else will be able to change it (save reflection tomfoolery).

user5090812
  • 888
  • 1
  • 7
  • 7
  • But I need to look in code for this. I want to see immediately its readonly with unchangeable uynderlying collection. So I need to create new type I think. – apocalypse Nov 09 '15 at 15:43
0

With a ReadOnlyCollection collection, you are sure that client code cannot modify the collection, i.e add or remove elements from the collection. But client code can still modify the items contained in your collection:

myReadOnlyCollection.Add(new Object())// error, cannot add/remove items to readonlyCollection
MyObjet obj = myReadOnlyCollection[3] // get the 3rd item in the collection, ok;

obj.someProperty = 9; // ops, the object contained in the ReadOnlyCollection has been changed!

You have two different problems to face:

  • ensure your collection will always contain the same objects -> use readOnlyCollections
  • ensure each object in the collection cannot be modified -> type T of the collection must be immutable
Gian Paolo
  • 4,161
  • 4
  • 16
  • 34
-1

Yes. You can use an instance of

ReadOnlyCollection<T>
Matt
  • 1,648
  • 12
  • 22