通过方法调用封装C#List

时间:2013-12-20 20:52:52

标签: c# encapsulation

在C#中,当我想封装一个List时,我将它放在一个类中,并在其中抛出一些辅助方法。但是,我注意到的是,每当我想迭代项目列表时,我就会返回列表。简单。然而,这有什么不好的是我无法判断列表是否被某些方法修改过了。

所以这就是我一直在做的事情:

class Animals
{
    private List<Dog> _dogs;

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

}

为了反驳这一点,我想到了:

class Animals
{
    private List<Dog> _dogs;

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

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

我对这种方法的真正问题在于,每次我想要列表中的项目时,都必须调用一个方法。这意味着如果我想迭代列表,我必须设置一个循环,每次迭代调用Animals.Count Animals.GetDog(i)次。

这会影响我的计划吗?有没有更合适的方法来完成同样的事情?

我已经看过封装列表的方法,但它们看起来非常错综复杂。我的主要目的是不将_dogs列表公开给类外的任何内容。

3 个答案:

答案 0 :(得分:6)

您可以使用IEnumerable轻松封装列表:

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

这允许您从类外部枚举列表,但无法访问基础列表。

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

答案 1 :(得分:2)

您可以返回ReadOnlyCollection而不是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; }
}

这样您就可以对列表进行更改,而不允许其他任何访问Dogs属性的人更改它。这也允许用户始终拥有更新的集合,而不是始终返回列表的副本。

答案 2 :(得分:1)

解决问题的常用方法是返回列表的只读快照,例如

public ReadOnlyCollection<Dog> Snapshot
{
    get
    {
        return new ReadOnlyCollection<Dog>(_dogs);
    }
}