1

I just looked into IReadOnlyList<T> to create readonly list. But I think it is not 100% readonly. I can not add/remove the item from the list but I can still modify the members.

Consider this example.

class Program
{
    static void Main(string[] args)
    {
        List<Test> list = new List<Test>();
        list.Add(new Test() { MyProperty = 10 });
        list.Add(new Test() { MyProperty = 20 });

        IReadOnlyList<Test> myImmutableObj = list.AsReadOnly();

        // I can modify the property which is part of read only list
        myImmutableObj[0].MyProperty = 30;
    }
}

public class Test
{
    public int MyProperty { get; set; } 
}

To make it truly readonly I have to make MyProperty as readonly. This is a custom class, it's possible to modify the class. What if my list is of inbuilt .net class which has both getter & setter properties? I think in that case I have to write a wrapper of that .net class which only allows reading the value.

Is there any way to make the existing classes immutable?

Atul Sureka
  • 3,085
  • 7
  • 39
  • 64
  • The list *is* immutable. Just shallow immutable, whereas you expect deep immutability. See [Kinds of Immutability](http://blogs.msdn.com/b/ericlippert/archive/2007/11/13/immutability-in-c-part-one-kinds-of-immutability.aspx) for this and other important distinctions. –  Jun 09 '13 at 17:45
  • I burn my classes onto ROMs, then socket them onto daughterboards that fit into the PCIe slots on the motherboard of the computer. – Tyler Durden Jun 09 '13 at 17:50
  • @delnan: No; it's actually just read-only. – SLaks Jun 09 '13 at 17:53

2 Answers2

6

You're confusing the terms immutable and read-only.

A read-only object is an object that does not expose any way to change it. ReadOnlyCollection<T> (returned by AsReadOnly()) is a good example). However, IEnumerable<T> is also read-only.
The important distinction is that read-only objects are allowed to change.

If you write list.Add(new Test()), your read-only collection (which just wraps list) will have changed.

Read-only collections are useful for designing safe APIs, where only the owner of the collection is allowed to change it.
However, it won't do any good for thread-safety.


An immutable object is an object that cannot change at all, no matter what happens (Reflection doesn't count). string is an excellent example of an immutable class; the value of an existing string instance can never change, no matter what happens. (barring reflection, unsafe code, and certain marshalling tricks)

.Net does not have any built-in immutable collections, but the CLR team released a library of immutable collection types on NuGet.

Truly immutable objects are intrinsically thread-safe. Since there is no way to modify them, there is no chance that other threads will observe an inconsistent instance.


You're asking about deep immutability.
An object is deeply immutable if every object recursively accessible through its properties (the entire object graph) is itself deeply immutable.

You can't make a deeply immutable object unless you make an immutable version of every class it needs to reference. These immutable versions need to copy the state from the mutable original classes; they cannot simply wrap the original instance, or it would still be mutable though the inner instances.

You could instead make a deeply read-only object by making a read-only wrapper around the mutable class.


For more information, see my blog.

SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
  • 1
    For an object to be immutable, any outside objects whose *state it encapsulates* must also be immutable, but that does not imply that an immutable object can't hold references to mutable objects *if those references are used to encapsulate the identity of those objects, rather than their state*. A unicast delegate is a prime example of that. A `Func`, for example, might return 1 the first time it's called, 2 the second, etc. `Method` would never change, and the identity of the object referred to by `Target` would never change, but the object could do whatever it wants to itself. – supercat Jun 13 '13 at 20:30
2

A truly immutable class is one whose properties and fields are all read-only. This definition is recursive in that all classes contained within this class's fields and properties must ALSO be read only. Your read-only list is not truly immutable, because the contents of the list are NOT immutable since as you said you can modify them. The individual items in the list would have to be read-only as well for the IReadOnlyList<T> to truly be immutable.

Haney
  • 32,775
  • 8
  • 59
  • 68