Question

In C# when I want to encapsulate a List I place it inside of a class and throw some helper methods in there with it. However, what I have noticed is that whenever I want to iterate over the list of items I just return the list. Simple. However, what is bad about this is that I am unable to tell if the list has been modified by some method gone wrong.

So this is what I have been doing:

class Animals
{
    private List<Dog> _dogs;

    public List<Dog> Dogs
    {
        get { return _dogs; }
    }

}

To conteract this I thought of doing:

class Animals
{
    private List<Dog> _dogs;

    public Dog GetDog(int dogid)
    {
        return _dogs[dogid];
    }

    public int Count
    {
        get { return _dogs.Count; }
    }
}

My real issue with this method lies in the fact that every single time I want an item from the list, a method must be called. This means that if I want to iterate over the list, I must setup a loop to go for Animals.Count number of times calling Animals.GetDog(i) every iteration.

Is this going to affect my program? Is there a more suitable way of accomplishing the same thing?

I've had a look at ways of encapsulating Lists, but they seem quite intricate. My main aim is to not expose _dogs list to anything outside of the class.

Was it helpful?

Solution

You can use an IEnumerable to encapsulate the list quite easily:

public IEnumerable<Dog> GetDogs()
{
    foreach (Dog dog in _dogs)
    {
        yield return dog;
    }
}

This allows you to enumerate the list from outside the class, but not have access to the underlying list.

//Outside Animals class
foreach (Dog dog in animalObj.GetDogs())
{
    //do stuff
}

OTHER TIPS

You can return a ReadOnlyCollection rather than a List:

public class Animals
{
    public Animals()
    {
        myModifiableDogList = new List<Dog>();
        Dogs = new ReadOnlyCollection<Dog>(myModifiableDogList);
    }

    private IList<Dog> myModifiableDogList;
    public ReadOnlyCollection<Dog> Dogs { get; private set; }
}

This way you can make changes to the list, not allowing anyone else accessing the Dogs property to change it. This also allows the user to always have an updated collection, as opposed to always returning a copy of the list.

A pretty common approach to solve your problem to return a read only snapshot of your list, e.g.

public ReadOnlyCollection<Dog> Snapshot
{
    get
    {
        return new ReadOnlyCollection<Dog>(_dogs);
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top