BendEg
BendEg

Reputation: 21088

Prevent public List property from adding items

Is it possible to prevent a public property of the type IList<> from adding items. For example i have this simple code, which stores some instances in a simple list:

class Program
{
    private static IList<SomeItem> items = new List<SomeItem>();

    static void Main(string[] args)
    {
        // That ok
        Items.Add(new SomeItem { OrderId = 0 });
        Items.Add(new SomeItem { OrderId = 1 });
        Items.Add(new SomeItem { OrderId = 2 });

        Console.WriteLine("Amount: {0}", items.Count);

        // This should not be possible
        OrderedList.Add(new SomeItem { OrderId = 3 });
        OrderedList.Add(new SomeItem { OrderId = 4 });

        Console.WriteLine("Amount: {0}", items.Count);
        Console.ReadLine();
    }

    public static IList<SomeItem> Items
    {
        get
        {
            return items;
        }
    }

    public static IList<SomeItem> OrderedList
    {
        get
        {
            return items.OrderBy(item => item.OrderId).ToList();
        }
    }
}

My API should expose some property, which returns a list of ordered items (OrderedList). This is all fine, but it should not be possible to add items to this list, because they will not be stored in items. Should i create my own read only list or am i missing some better solution. Thank you very much!

EDIT

In short: this should not be possible: OrderedList.Add(new SomeItem { OrderId = 4 });

Upvotes: 1

Views: 105

Answers (2)

Markus
Markus

Reputation: 22456

Instead of publishing the IList<T>, I'd propose to keep the list internal and only publish a IReadOnlyList<T>:

public static IReadOnlyList<SomeItem> OrderedList
{
    get
    {
        return items.OrderBy(item => item.OrderId).ToList().AsReadOnly();
    }
}

You can use the AsReadOnly method to create a readonly version of your list. This way, you return a ReadOnlyCollection<T> so the caller is unable to cast the property value to an IList<T>. Otherwise the caller can do this cast and add items nevertheless.

Upvotes: 2

Dmitrii Bychenko
Dmitrii Bychenko

Reputation: 186668

If IList<T> can't be added, that's in fact IReadOnlyList<T>:

public static IReadOnlyList<SomeItem> OrderedList {  
  get {
    // IList<T> implements IReadOnlyList<T>, so just return List here
    ...
  }
}

Upvotes: 3

Related Questions