的一般情况的一个例子:返回一个不可变集合当物品必须是可变的最初
public class Validator
{
// ...
public ReadOnlyCollection<InvalidContainer> ContainersUnderMinimum
{
get { return _containersUnderMinimum.AsReadOnly(); }
}
}
public class InvalidContainer
{
// ...
public int LowestVolume { get; set; }
}
上面的验证类需要在其构造的其他项目的集合,然后将无效项内部列表。每个容器都有许多小容器(想想试管架),而班级希望找到最低容量。当找到物品(管)时,构造函数将添加到列表中,并在找到物品时更新现有列表对象。
的问题是验证要返回不可变对象的只读集合,但对象(InvalidContainers)必须是可变的施工后,这样的值可以是(基本上)积累。
重构使用的接口(IInvalidContainer)导致头痛,如通用集合不能被转换为基本类型的集合。
有什么好的模式或做法来解决这个问题?
编辑:为了澄清,其意图是具有属性值(集合)是不可变的。我知道ReadOnlyCollection只强制收集而不是收集项目的不变性。通常我会让项目不可变,但我不能在这个(和类似的)案例中。但是,我只希望在构造Validator类时突变。防止打电话者做不明智的事情并不是设计目标;目标是避免诱惑拥有可设置公共财产的呼叫者。
编辑:改变了标题为清楚起见。
编辑:这里的重构版本(基于LBushkin和递归建议):
public IEnumerable<IInvalidContainer> ContainersUnderMinimum
{
get
{
return _containersUnderMinimum.Cast<IInvalidContainer>();
}
}
我担心的是,这是每一个属性被访问时创建一个新的列表。但是由于我经常抱怨过早的优化,这种担忧可能是没有根据的。 – TrueWill 2010-01-20 18:23:27
你不一定需要建立一个新的列表。可以使用类似于'ReadOnlyCollection <>'的方法,并创建也动态地包装使用不可变的包装对象现有的列表元素的衍生物。事实上,你可以写一个返回扩展方法的'的IEnumerable <>'使用产量推迟评估当列表迭代到(假设你不需要直接索引)。 – LBushkin 2010-01-20 18:48:37
这让我觉得,如果我需要* *优化,我可以做在构造函数中的演员/ ToList(填充回收后),并分配到其他领域。但是我怀疑你的收益率回报建议(或者只是将演员投入收益人)是一个更简单的选择。 – TrueWill 2010-01-21 14:48:47