TOP KEK
TOP KEK

Reputation: 2661

Prevent dictionary from modifications

How do I prevent dictionary items from modification outside of my class? I have to expose collection of objects as a property, but then everyone can do everything with my objects. I tried to use ReadOnlyDictionary to wrap my public property, but IntegerValue property still can be modified from outside.

Sample code is below:

internal class MyRefClass
{
    public object ReferenceStrig;
    public int IntegerValue;

    public MyRefClass()
    {
     ReferenceStrig = "Initialized string";
        IntegerValue = 100;
    }
}

class Program
{
    static void Main(string[] args)
    {
        var writableDict = new Dictionary<int, MyRefClass>();
        writableDict.Add(1,new MyRefClass());

        ReadOnlyDictionary<int, MyRefClass> dict = new ReadOnlyDictionary<int, MyRefClass>(writableDict);

    MyRefClass variable;
    dict.TryGetValue(1, out variable); #get an object from dictionary
    variable.IntegerValue = 0; #changing property of the object

    writableDict.TryGetValue(1, out variable); #get the same object once again
    #now property variable.IntegerValue == 0 instead of 100!
    }
}

Upvotes: 0

Views: 1916

Answers (2)

Sriram Sakthivel
Sriram Sakthivel

Reputation: 73502

If you want to expose an object to "Client code" and yet you want the object not to be modified then you must return a "Immutable type". Either in the form of immutable class or an interface with only readonly properties.

This also means that all the properties and nested properties and so on of your type should also be "Immutable" otheriwse they will be still able to modify the nested members. In other words All types in object graph of the type you expose must be Immutable.

Another option is to clone the object and return the copy and forget about the modifications. But be sure you're doing a Deep-Copy and not Shallow-Copy. Shallow copy suffers from aforementioned problem.

Upvotes: 5

Matthew Watson
Matthew Watson

Reputation: 109852

Make your class immutable, for example:

class MyImmutableRefClass
{
    public readonly object ReferenceStrig;
    public readonly int IntegerValue;

    public MyImmutableRefClass(): this("Initialized string", 100)
    {
    }

    public MyImmutableRefClass(string referenceStrig, int integerValue)
    {
        ReferenceStrig = referenceStrig;
        IntegerValue   = integerValue;
    }
}

This isn't really enough if ReferenceStrig is an object which itself isn't immutable. It works for this particular example because it can only be a string (which is itself immutable). But if it was some other type, then that type would have to be immutable itself - and (recursively) any public fields and properties that it contains would also have to be immutable. (I call that "deep-immutable".)

Here's an interesting series of articles on immutability in C#:

http://blogs.msdn.com/b/ericlippert/archive/2007/11/13/immutability-in-c-part-one-kinds-of-immutability.aspx

Upvotes: 1

Related Questions