Information Technology Reference
In-Depth Information
exception, you are faced with a tough choice: You can either create a defen-
sive copy of all the objects used in the loop, or you can lower your expec-
tations and support only the basic exception guarantee. There are no hard
and fast rules, but copying heap-allocated objects in a managed environ-
ment is not as expensive as it was in native environments. A lot of time
has been spent optimizing memory management in .NET. I prefer to sup-
port the strong exception guarantee whenever possible, even if it means
copying a large container: The capability to recover from errors outweighs
the small performance gain from avoiding the copy. In special cases, it
doesn't make sense to create the copy. If any exceptions would result in
terminating the program anyway, it makes no sense to worry about the
strong exception guarantee. The larger concern is that swapping reference
types can lead to program errors. Consider this example:
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;
}
This looks like a great use of the defensive copy mechanism. You've created
a copy of your data. Then you grab new data from somewhere to fill the
temporary data. Finally, you swap the temporary storage back. It looks
great. If anything goes wrong trying to retrieve the data, you have not made
any changes.
There's only one problem: It doesn't work. The MyCollection property
returns a reference to the data object (see Item 26). All the clients of this
class are left holding references to the original BindingList<> after you call
UpdateData. They are looking at the old view of the data. The swap trick
 
Search WWH ::




Custom Search