コード検査: 変更されたキャプチャー変数へのアクセス
まず、クロージャ(英語)とは何かを理解していることを確認しましょう。簡単に言うと、C# のクロージャは、ラムダ式または外部スコープからいくつかの変数をキャプチャーする匿名メソッドです。最も簡単な例を次に示します。
上記の例では、print
は変数 myStr
(その値ではなく)をキャプチャーし、print()
を呼び出したときにのみ myStr
の値を取得します。
より複雑なシナリオでは、クロージャが変化するコンテキストで定義されると、期待通りに動作しないことがあります。
ループ内で上記のクロージャを定義する例を次に示します。
意外にも、このコードは、myActions[0]();
を呼び出すときに ArgumentOutOfRangeException
を生成します。直感的に見えるかもしれない Console.WriteLine(myStrings[0]);
を実行する代わりに、この呼び出しは Console.WriteLine(myStrings[i]);
を実行しようとします。i
は for
サイクル全体にスコープされ、その値は 0
に等しくなく、2
にも等しくない(これは条件本当だった)。最後の ++
演算の結果、条件が偽になる直前の値が 3
になり、ループを終了しました。myStrings
は 3 つの要素しか持たないため、myStrings[3]
は ArgumentOutOfRangeException
につながります。
JetBrains Rider は、ここでは ArgumentOutOfRangeException
の形をとる結果を推論しませんが、問題の原因 (クロージャ内の反復変数) を正しく指摘し、変化する変数の値をスコープにコピーすることで問題を修正することを提案します。クロージャが定義されている場所:
この修正により、myActions
からアクションを選択し、このアクションが作成されたコンテキストを取得すると、i1
はリスト内のアクションのインデックスに対応する値を保持します。
関連ページ:
![](https://resources.jetbrains.com/help/img/rider/2024.1/code_analysis_target_framework.png)
コードインスペクション設定を構成する
設計時コードインスペクションを構成する:デフォルトでは、JetBrains Rider はサポートされている言語に対応するすべてのファイルで設計時コードインスペクションを有効にします。必要に応じて、無効にすることができます。設計時コードインスペクションが有効かどうかにかかわらず、コードインスペクションを特定の範囲でいつでも実行できます。「鉛筆」ウィジェットを使用して、エディターから直接インスペクション設定をすばやく調整するか、設定でより詳細な構成を行うことができます。を押すか、メニューから(W...
![](https://pleiades.io/icons/rider.png)
コード検査: クロージャの foreach 変数へのアクセス
まず、クロージャとは何かを理解していることを確認しましょう。簡単に言うと、C# のクロージャは、ラムダ式または外部スコープからいくつかの変数をキャプチャーする匿名メソッドです。最も簡単な例を次に示します。// A self-contained lambda. Not a closure. Action printOne = () => { Console.WriteLine("one"); }; // A closure – a lambda that captures a variabl...