私が書いたコードで繰り返し発生する問題に直面しています。グローバル値を変更し(例としてレジストリ値を使用します)、変更を元の状態に戻そうとします。
この問題を解決するためにIDisposableを使用しようと思いました。作成されると、オブジェクトはレジストリ値を読み取り、ローカルに保存してから変更します。破壊されると、設定が元に戻ります。次のように使用されます。
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
1つの変更のみが行われた場合は、うまく機能するはずです。しかし、複数の変更が行われた場合、または呼び出し元が'using'構文を使用してオブジェクトを作成しない場合、問題が発生していることがわかります。
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!!!
呼び出し元がオブジェクトを手動で破棄すると、問題はさらに悪化します。これにより、私のアプローチには欠陥があると思います。
この問題を解決するために受け入れられているパターンはありますか?クラスに静的スタックを追加すると役立つかもしれないと思っていました。
オブジェクトが破壊される順序は何らかの方法で保証されていますか?IDisposableを試してみようと思いましたが、他の解決策に耳を傾けています。