在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
列表公开给类外的任何内容。
答案 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);
}
}