方便或“懒惰编程”IList管理 - 保护IList.Add方法

时间:2009-02-16 18:45:26

标签: c# architecture

当您拥有包含项目列表的对象时,如何管理此简单方案。 EG:

public class ContainerObject
{
    IList<ChildObject> Children { get; }

    public void AddCustom(ChildObject toAdd)
    {
        // Some validation ...
        Children.Add(toAdd);
    }
}

假设集合初始化为IList的实现,有没有办法控制项目添加到列表的方式?

例如,我在ContainerObject类上有另一个方法,它接受一个ChildObject并将其添加到列表中。在添加之前,需要此方法对ChildObject执行一些基本验证。

我很懒,因为我不想乱搞并编写一个消费开发人员需要实现的自定义列表界面(没有添加方法)。我也在IQueryable接口上使用ToList()方法,所以这是坚持IList的另一个原因 - 它只是起作用。

那么,有没有一种方法可以监管如何将项目添加到IList实例,即阻止使用Add方法,只允许通过我的自定义方法添加到集合中,或者我只是要求不可能? ......而且懒惰:(

我可以想到一些hacky方法来检查何时通过我的自定义方法添加项目或直接在列表中添加项目但这些看起来很糟糕!

任何人都有类似的经历吗?如果是这样,你做了什么?

2 个答案:

答案 0 :(得分:5)

您可以使用ReadOnlyCollection<T>使您的属性返回原始列表的包装器。这将确保呼叫者不会自己添加任何项目。您可以保留对原始可变列表的引用。请注意,因为只读集合只是一个包装器,所以缓存只读集合的​​调用者仍会看到您对原始列表所做的添加。根据您的预期用途,这可能是也可能不是好事。

编辑:解释我的缓存评论......

假设客户做了:

IList<ChildObject> originalChildren = container.Children;    
container.AddChild(new ChildObject());
IList<ChildObject> updatedChildren = container.Children;    

实现Children属性,如下所示:

private IList<ChildObject> children = new List<ChildObject>();
public IList<ChildObject> Children
{
    get { return new ReadOnlyCollection<ChildObject>(children); }
}

然后originalChildrenupdateChildren都会有相同的内容 - 返回的ReadOnlyCollection不会是第一个孩子集合的快照线。它只是集合周围的包装器。客户无法依赖它而不会改变 - 他们自己也无法改变它。

答案 1 :(得分:2)

ReadOnlyCollection返回到包含您管理添加到的列表的世界。