2011-08-23 98 views
0

这是我在Effective C#书中看到的例子:swaping集防御性副本

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

对不对?

+2

这里很难遵循你的思路。请详细说明。 –

回答

0

集合是一个引用类型,所以其他保存代码将看到旧数据。

两种可能的解决方案:

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

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

+0

第二期opt如何提供帮助? –

+0

您的类将通过实现控制枚举的逻辑来控制对PayrollData的访问。因此,您可以准确控制数据更改的时间以及枚举中正在进行的迭代会发生什么情况。 –

+0

此外,您可以避免其他人执行诸如instance.MyCollection.Clear()等清除所有项目的数据字段的情况。 –