集合属性应该只读 - 漏洞?(Collection properties should be rea

2019-09-19 03:57发布

在秉承代码分析错误的过程中,我改变了我的属性有私人setter方法。 然后,我开始试图理解为什么多一点。 从一些研究,MS说这个 :

可写的集合属性允许用户以一种完全不同的集合取代集合。

而答案, 在这里 ,说:

一个上添加一个公共设置器List<T>对象是危险的。

但为什么它的危险的原因未列出。 而这也正是我很好奇的部分。

如果我们有这个集合:

public List<Foo> Foos { get; set; }

为什么让二传手私人? 显然,我们不希望客户端的代码替换集合, 但如果客户端可以删除每一个元素,然后添加任何他们想要的,这有什么意义 ? 那是不一样的更换整个集合? 如何值按照该代码分析规则提供?

Answer 1:

不暴露setter方法防止其中收集指定的值的情况下null 。 有之间的差异null没有任何价值和收藏。 考虑:

for (var value in this.myCollection){ // do something

当没有值(即有人呼吁Remove每个值),什么也没有发生。 当this.myCollection为空,然而,一个NullReferenceException将被抛出。

代码分析正在假设你的代码不检查myCollection是它在操作之前空。

这可能也是中定义的线程安全的集合类型的额外保障System.Collections.Concurrent 。 试想某个线程试图overwritting它来代替整个集合。 通过摆脱公众二传手,线程具有唯一的选择就是调用线程安全的AddRemove方法。



Answer 2:

如果你暴露一个IList(这将是更好的做法),消费者可以与一个完全不同的类实现IList,这可能会产生无法预料的影响更换集合。 你可以订阅了事件的该集合,或对集合,你现在不当回应中的项目。



Answer 3:

除了SimpleCoder的空检查(这是当然的,重要的),还有你需要考虑其他的事情。

  • 有人可能会更换名单,导致线程安全的大问题
  • 事件的更换列表将不会被发送到旧的用户
  • 你露出很多,很多的行为,那么你需要。 例如,我甚至不会使吸气公众。

为了澄清点3,不要做cust.Orders.clear()但做一个函数调用clearOrders()来代替。

如果客户是不允许走在信用额度? 你无法控制的,如果你暴露的名单。 你必须检查(和所有其他这块业务逻辑的),每一个地方,你可以添加一个订单。 哎呀! 这对错误有很大的潜力。 相反,你可以把它所有在addOrder(Order o)功能,是正确的雨。

对于几乎每一个(我说的每一个,但有时欺骗的感觉很好......)业务类,每个属性应该是私有的get和set,而如果可行的话让他们只读了。 这样一来,你的类的用户只得到行为。 保护多达你的数据,你可以!



Answer 4:

ReadOnlyCollection和ReadOnlyObservableCollection只存在于只读集合scenearios。

ReadOnlyObservableCollection是一个方式WPF / Silverlight中/城域应用结合是非常有用的。



Answer 5:

如果你有一个列表属性一个Customer类则此属性应该始终有其他的私人二传手它可以从通过客户对象外修改:

customer.Orders = new List<Order> 
//this could overwrite data.

始终使用添加和删除收集的方法。

该订单列表应通过客户构造内创建:

Orders = new List<Order>();

你真的想在你的代码到处请检查是否customer.Orders != null然后在订单操作?

或者你在你的客户对象创建订单财产的建议,永不检查customer.Orders == null ,而不是仅仅列举了订单,如果计数为零没有任何反应......



文章来源: Collection properties should be read only - Loophole?