I face a recurring problem in the code I write: modifying some global value (I'll use a registry value just as an example) and then trying to revert the modifications to original state.
I thought I'd try to use IDisposable to solve this problem. When created, the object would read the registry value, store it locally, and then modify it. When destroyed, it would revert the setting. It would be used something like this:
using(RegistryModification mod = new RegistryModification("HKCR\SomeValue", 42))
{
// reg value now modified to 42, do stuff
} // Object gets disposed, which contains code to revert back the setting
Should work great, if only 1 modification is ever made. But if multiple modifications are made, or the caller does not create the objects with the 'using' construct, I can see trouble occuring.
public void Foo()
{
// assume HKCR\SomeValue starts as '13'
// First object reads HKCR\SomeValue and stores '13', then modifies to 42
RegistryModification mod1 = new RegistryModification("HKCR\SomeValue", 42);
// Next object reads HKCR\SomeValue and stores '42', then modifies to 12
RegistryModification mod2 = new RegistryModification("HKCR\SomeValue", 12);
}
// objects are destroyed. But if mod1 was destroyed first, followed by mod2,
// the reg value is set to 42 and not 13. Bad!!!
The problem worsens if a caller manually disposes the object. This leads me to think my approach is, simply, flawed.
Is there some sort of accepted pattern to solve this problem? I was thinking adding a static stack to the class might help.
Is the order that objects are destroyed guaranteed in any way? I thought I'd try with IDisposable, but am all ears for other solutions.