I have a class that maintains list of objects of another class. List of objects is a public property. I would like to prevent users from adding and removing objects directly
Your easiest option would be to expose your list as one of the following IEnumerable, ICollection ReadOnlyCollection via a public property.
So you could create your own type
of list which exposes your Items
as one of the above but has an internal method for the adding e.g.
public class MyList<MyType>
{
private List<MyType> items;
public MyList()
{
items = new List<MyType>();
}
public IEnumerable Items { get { return items.AsEnumerable(); } }
public Add(MyType item)
{
// do internal processing
items.Add(item);
}
}
Doesn't really answer your question, but is useful information if you decide to implement one of your two ideas: You can use ToArray to create a copy and return an array.
Or you can do something like this: http://en.csharp-online.net/CSharp_Generics_Recipes%E2%80%94Making_Read-Only_Collections_the_Generic_Way
Out of the box, only IEnumerable<T>
will provide this without exposing any Add
and Remove
public methods that might trick the client into getting a runtime exception.
If you want your public API to explicitely state that the collection is read-only and you need an indexer, you will have to write your own wrapper around existing List<T>
or T[]
.
You can use ReadOnlyCollection - wrap your collection in this and return the ReadOnlyCollection
to users of your class:
return new ReadOnlyCollection(innerCollection);
Or using the AsReadOnly
method of the List<T>
class:
return innerCollection.AsReadOnly();
The IEnumerable interface will do what you need, as it only has one member GetEnumerator()
, that will only let you iterate over items.
Maybe AsReadOnly method will do the trick, to hand a read-only instance to public.
Otherwise, IEnumerable<T>
has no Add
nor Remove
, so you can do something like:
private List<int> _myList;
public IEnumerable<int> MyList
{
get
{
return this._myList.ToList();
}
}
I would rather go for the IEnumerable<T>
(+ copy) as for ReadOnlyCollection<T>
, because: changes to your base list (which your read-only collection is created from) will immediately show up in your instance of the read-only collection. this may cause locking and straaange problems :)
ICollection (the non-generic version) only got IEnumerable + Count