有些时候,这种强保证只是效率很低而不被支持,而且有些时候,你不能支持不发生潜在BUG的强保证。开始的那个也是最简单的那个例子是一个循环构造。当上面的代码在一个循环里,而这个循环里有可能引发程序异常的修改,这时你就面临一个困难的选择:你要么对循环里的所有对象进行拷贝,或者降低异常保证,只对基本保证提供支持。这里没有固定的或者更好的规则,但在托管环境里拷贝堆上分配的对象,并不是像在本地环境上那开销昂贵。在.Net里,大量的时间都花在了内存优化上。我喜欢选择支持强异常保证,即使这意味要拷贝一个大的容器:获得从错误中恢复的能力,比避免拷贝获得小的性能要划算得多。在特殊情况下,不要做无意义的拷贝。如果某个异常在任何情况下都要终止程序,这就没有意义做强异常保证了。我们更关心的是交换引用类型数据会让程序产生错误。考虑这个例子:
这看上去很不错,使用了被动式的拷贝机制。你创建了一个DataSet的拷贝,然后你就从数据库里攫取数据来填充临时的DataSet。最后,把临时存储交换回来。这看上去很好,如果在取回数据中发生了任何错误,你就相当于没有做任何修改。 这只有一个问题:它不工作。MyCollection属性返回的是一个对_data对象的引用。所有的类的使用客户,在你调用了UpdateData后,还是保持着原原来数据的引用。他们所看到的是旧数据的视图。交换的伎俩在引用类型上不工作,它只能在值类型上工作。因为这是一个常用的操作,对于DataSets有一个特殊的修改方法:使用Merge 方法:
合并修改到当前的DataSet上,就让所有的用户保持可用的引用,而且内部的DataSet内容已经更新。 在一般情况下,你不能修正像这样的引用类型交换,然后还想确保用户拥有当前的对象拷贝。交换工作只对值类型有效,这应该是足够了。