How to make List's Add method protected, while exposing List with get property?

Viewed 13096

I have a class named WhatClass that has List field in it. I need to be able to read-only this field, so I used a get property to expose it to other objects.

public class WhatClass
{
    List<SomeOtherClass> _SomeOtherClassItems;

    public List<SomeOtherClass> SomeOtherClassItems { get { return _SomeOtherClassItems; } }
}

However it turns out that any object can call

WhatClass.SomeOtherClassItems.Add(item);

How can I prevent this?

7 Answers

List<T> implements IReadOnlyList<T> since .NET Framework 4.5, so an internal list can be exposed as IReadOnlyList<T> instead for that purpose.

public class WhatClass
{
    List<SomeOtherClass> _SomeOtherClassItems;

    public IReadOnlyList<SomeOtherClass> SomeOtherClassItems => _SomeOtherClassItems;
}

You can just use ToList() to return a copy of the list instead. Other classes can do what they like to the copy it won't alter your original list.

You should make it clear in the name that they are getting a copy.

using System.Linq;

public class WhatClass
{
    List<SomeOtherClass> _SomeOtherClassItems;

    public List<SomeOtherClass> SomeOtherClassItems { get { return _SomeOtherClassItems.ToList(); } }
}

Although others have pointed out the use of ReadOnlyCollection, it's worth noting that there also exists a cool ReadOnlyObservableCollection. It can be really useful in bindings and view models. As pointed here:

This class is a read-only wrapper around an ObservableCollection. If changes are made to the underlying collection, the ReadOnlyObservableCollection reflects those changes. To be notified of the changes to this class, subscribe to the CollectionChanged or PropertyChanged event.

You can simply expose this ReadOnlyObservableCollection and make changes to the underlying collection and rest assured that your view is getting updated.

Related