为什么接口上的Dictionary<k,v>
是个坏主意?
由于
答案 0 :(得分:6)
因为即使你制作了readonly
或const
,也不会阻止客户修改字典的内容(没有你的规定)。这同样适用于公共接口上的数组和列表。
要解决这个问题,您可以将容器的副本提供给客户端(如他/她的评论中提到的jk),或者(复制整个容器的代价太高)为它提供访问器方法getItem
和setItem
。这样您就可以控制容器的内容。
答案 1 :(得分:2)
首先,人们应该更喜欢通过他们的界面和具体类型公开集合,因为这有助于避免暴露出正在使用的集合类型,并使类编写者(接口实现者)可以自由地利用任何集合最佳套件给定需要/约束。例如,我可以从一个接口公开一个IList,然后作为实现这个接口的类的实现者,我可以自由选择使用我所需要的sortlist,bag,set或任何最佳套件。
是否应该从接口公开集合是有争议的 - 如果从类中公开List并且类具有管理是否可以向集合中添加项的严格规则,那么是什么阻止客户端操作直接收集,从而规避了任何逻辑。与此相反,AddItem方法可以保证只添加正确的项目。
在字典案例中,您可以将项目公开为IEnumerable<KeyValuePair<k,v>>
,并使用find方法为我们提供使用常规字典搜索机制查找项目的能力。或者,您可以将其公开为IDictionary,然后返回只读字典实现
答案 2 :(得分:2)
如果在修改字典时需要触发操作或限制对字典的访问(作为示例禁止删除),则必须在接口中提供包装字典的方法。此外,如果您想要替换底层容器(在这种情况下是字典),您将获得灵活性。
List<>
有一个不错的功能:AsReadOnly()
方法返回只读的IList<>
实现。
答案 3 :(得分:1)
您是在谈论将它们作为属性公开吗?
因为填充某些内容的IDictionary<k, v>
类型的方法参数非常有用。与列表中使用的AddRange(IEnumerable<T>)
函数非常相似。
请注意,我使用的是界面 IDictionary<k, v>
,而不是具体的类......