【问题标题】:swaping a collection with defensive copy用防御副本交换收藏
【发布时间】:2011-08-23 21:34:41
【问题描述】:

这是我在Effective C# 书中看到的一个例子:

private BindingList<PayrollData> data; 
public IBindingList MyCollection 
{
get { return data; } 
}
public void UpdateData() 
{
// Unreliable operation might fail: 
var temp = UnreliableOperation();
// This operation will only happen if 
// UnreliableOperation does not throw an 
// exception. 
data = temp;
}

作者说这适用于值类型而不是引用类型。 我不明白他的意思。

我想我现在明白了:集合是 ref 类型。 “数据字段”的消费者不会记得他们持有堆上旧存储的副本。 如果“数据”是值类型 - 消费者(使用数据的其他代码)会记得他们持有数据的深层副本,并会在需要更新时再次请求它。

对吗?

【问题讨论】:

  • 这里很难跟上您的思路。请详细说明。

标签: c# reference defensive-copy


【解决方案1】:

集合是一个引用类型,所以其他持有它的代码会看到旧数据。

两种可能的解决方案:

代替 data = temp 使用 data.Clear(); data.AddRange(temp) 将更改数据字段的内容。

或者最好删除 MyCollection 属性并使类实现 IEnumerable。这导致更好的封装。

【讨论】:

  • 您的类将通过实现控制枚举的逻辑来完全控制对 PayrollData 的访问。因此,您可以准确控制数据何时更改以及枚举中正在进行的迭代会发生什么。
  • 此外,您还可以避免出现其他情况,例如 instance.MyCollection.Clear() 会清除您的所有项目的数据字段。
猜你喜欢
  • 2011-01-15
  • 1970-01-01
  • 1970-01-01
  • 2019-04-09
  • 2016-02-26
  • 2011-02-26
  • 1970-01-01
  • 2013-10-12
  • 1970-01-01
相关资源
最近更新 更多