コード検査: Double-Check Locking パターンの実装が間違っている可能性があります。チェックされたフィールドへの読み取りアクセス。
次のコードを考えてみましょう。
Init() が Foo の状態を初期化するために使用される方法であると仮定すると、上記のコードはマルチスレッド環境では期待通りに機能しない可能性があります。
1 つのスレッドが _instance = new Foo(); を実行したがまだ _instance.Init(); を実行していない場合があります。この時点で他のスレッドが GetValue() を呼び出すと、メソッドは _instance が null ではないことを確認し、初期化されていないインスタンスが呼び出し元に返されます。
上記のコードでこの問題を解決するには、2 つの方法があります。
最初の、最も明白なことは、Init() の内容をプライベートコンストラクターに移動することです。
2 つ目は、チェックされていない変数で初期化を実行してから、チェックされた変数に割り当てることです。これにより、問題が解消されます。このようにして _instance はすでに初期化されているときだけ null にはなりません。上記の例の lock ステートメントのコードは、次のように書き直すことができます。
StackOverflow に関するこの回答(英語)は、このパターンに関する他の考えられる問題と、なぜ _instance を volatile と宣言すべきかを説明します。
関連ページ:
コードインスペクション設定を構成する
設計時コードインスペクションを構成する:デフォルトでは、ReSharper は、サポートされている言語に対応するすべてのファイルで設計時コードインスペクションを有効にします。必要に応じて、無効にすることができます。設計時コードインスペクションが有効かどうかに関係なく、コードインスペクションは常に特定のスコープで実行できます。メインメニューからを選択するか、Alt+R O を押してから、左側のを選択します。設計時コードインスペクションを切り替えるには、コード分析を有効にするチェックボックスを使用し...
コード検査: ダブルチェックロックパターンの誤った実装の可能性: チェックされたフィールドへの可能な複数の書き込みアクセス。| ReSharper ドキュメント
次のコードを考えてみましょう。public class Foo { private static Foo instance; private static readonly object padlock = new object(); public static Foo Get() { if (instance == null) { lock (padlock) { if (instance == null) { instance = new Foo(); } } } return instan...