ローカル関数に関連するエラーと警告を解決する

この記事では、コンパイラの次のエラーと警告について説明します。

  • CS8108: 動的な型を持つ引数を、ローカル関数 'method' のパラメーター 'parameter' に渡すことはできません。
  • CS8112: ローカル関数 'method' は 'static extern' とマークされていないため、本体を宣言する必要があります。
  • CS8321: ローカル関数 'method' は宣言されていますが、使用されることはありません
  • CS8421: 静的ローカル関数に 'variable' への参照を含めることはできません。
  • CS8422: 静的ローカル関数には、'this' または 'base' への参照を含めることはできません。

C# 7.0 でローカル関数が追加されました。 別のメンバー内でヘルパー メソッドを宣言できます。 この記事の診断では、ローカル関数の宣言、呼び出し、使用法、およびローカル関数の追加のキャプチャ制限 static 説明します。

ローカル関数本体

  • CS8112: ローカル関数 'method' は、'static extern' とマークされていないため、本体を宣言する必要があります。

ローカル関数が static extern宣言されている場合を除き、ローカル関数の宣言には本文を含める必要があります。 ローカル関数にブロック本体または式本体を追加します。 実装が外部から提供されている場合は、ローカル関数 static extern マークし、宣言が外部メソッドの規則に従っていることを確認します。

params パラメーターと動的引数

  • CS8108: 動的な型を持つ引数を、ローカル関数 'method' のパラメーター 'parameter' に渡すことはできません。

ローカル関数呼び出しでは、 dynamic 引数を params パラメーターに渡すことはできません。 呼び出しの前に、 params パラメーターで想定される要素型または配列型に値を変換します。 明示的に型指定された配列に値を格納し、その配列をローカル関数に渡すこともできます。

未使用のローカル関数

  • CS8321: ローカル関数 'method' は宣言されていますが、使用されることはありません

ローカル関数を宣言しても、到達可能なコードが呼び出さない場合、コンパイラはこの警告を報告します。 未使用のローカル関数を削除するか、それを含むメンバーから呼び出してください。 将来の変更でローカル関数を使用する場合は、必要になるまでソースから除外します。

静的ローカル関数で状態をキャプチャできない

  • CS8421: 静的ローカル関数に 'variable' への参照を含めることはできません。
  • CS8422: 静的ローカル関数には、'this' または 'base' への参照を含めることはできません。

staticローカル関数は、外側のスコープから状態をキャプチャできません。 thisを介してローカル変数、パラメーター、インスタンス メンバーを囲んだり、this自体を参照したりすることはできません。 ローカル関数に必要な各値をパラメーターとして渡します (CS8421、 CS8422)。 ローカル関数が外側のスコープから変数またはインスタンスの状態をキャプチャする必要がある場合は、 static 修飾子を削除します。

CS8422 の原因となる参照の例を次に示します。

public class C
{
    private int counter = 1;

    public void IncreaseCounter()
    {
        static void LocalFunc(int addition)
        {
            this.counter += addition;   // CS8422
            base.ToString();            // CS8422

            counter += addition;        // CS8422: implicit this
            ToString();                 // CS8422: implicit base
        }

        LocalFunc(10);
    }
}

CS8422 を修正するには、必要なインスタンス データをローカル関数に渡すか、ヘルパーをインスタンス コンテキストの外部に移動するか、ローカル関数がインスタンスの状態にアクセスする必要があるときにstaticを削除します。