用防御性副本交换一个集合

时间:2011-08-23 21:34:42

标签: c# reference defensive-copy

这是我在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类型。 “数据字段”的消费者不会记得他们将副本保存在堆上的旧存储中。 如果“数据”是值类型 - 消费者(使用数据的其他代码)将记住他们持有深度数据副本,并在需要更新时再次请求它。

对吧?

1 个答案:

答案 0 :(得分:0)

该集合是一种引用类型,因此其他保留代码将显示旧数据。

两种可能的解决方案:

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

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