C#

【C#】ローカル関数の基本

この記事ではC#のローカル関数の基本についてまとめます。

ローカル関数の定義

ローカル関数とは、メソッド内に定義されたメソッドのことです。 C#7.0以降で使用できます。

メソッド内にローカル関数を定義する

ローカル関数は通常のメソッドの定義と同じように定義できますがpublicやprivateなどのアクセス修飾子をつけることはできません。

コード

using System;

internal class Program
{
    static void Main(string[] args)
    {
        int Add(int a, int b)
        {
            return a + b;
        }

        int val = Add(1,2);
        Console.WriteLine("val={0}", val);
    }
}

出力結果

val=3

上記コードでは、7~10行目でローカル関数Addを定義しています。ローカル関数の配置されたメソッドを親メソッドと言います。上記の例でいえばMainが親メソッドになります。ローカル関数は親メソッド内でのみ有効です。

ところで上記コードでは、ローカル関数Addは12行目で使用されていますが、コードの前で使用して、コードの後ろで定義することもできます。つまり上記コードは下記のように書いても同じです。

コード

using System;

internal class Program
{
    static void Main(string[] args)
    {
        int val = Add(1,2);
        Console.WriteLine("val={0}", val);
        
        int Add(int a, int b)
        {
            return a + b;
        }
    }
}

ブロック内にローカル関数を定義する

ローカル関数をブロック内で定義すると、そのローカル関数はブロック内でのみ有効です。ブロックの外からは利用できません。

コード

using System;

internal class Program
{
    static void Main(string[] args)
    {
        int val;

        //ブロック
        {
            val = Add(1, 2);

            int Add(int a, int b)
            {
                return a + b;
            }
        }

        Console.WriteLine("val={0}", val);
    }
}

出力結果

val=3

上記コードでは、ローカル関数Addをブロック内で定義しています。このようにブロック内で定義されたローカル関数はブロック内でのみ有効です。ブロックの外からはアクセスできません。

親メソッドのローカル変数へのアクセス

メソッド内で定義されたローカル関数は親メソッドのローカル変数にアクセスすることができます。このとき、親メソッドのローカル変数が割り当てられる前にローカル関数を呼び出すことはできません。また、親メソッドのローカル変数が宣言される前にローカル関数を定義することはできません(割り当てられていなくてもOK)。

コード

using System;

internal class Program
{
    static void Main(string[] args)
    {
        int a = 10;
        int val = Add(2);
        Console.WriteLine("val={0}", val);

        int Add(int b)
        {
            return a + b;
        }
    }
}

出力結果

val=12

下記コードのようにローカル関数がブロック内であっても親メソッドのローカル変数を使用することはできます。

コード

using System;

internal class Program
{
    static void Main(string[] args)
    {
        int a=10 ;

        int val ;
        {
            val = Add(2);
            int Add(int b)
            {
                return a + b;
            }
        }
        Console.WriteLine("val={0}", val);
    }
}

出力結果

val=12

静的ローカル関数

staticをつけることにより、静的ローカル関数を定義することができます。静的ローカル関数では外部(親メソッドや親ブロック)のローカル変数にアクセスできなくなります。

コード

using System;

internal class Program
{
    static void Main(string[] args)
    {
        int x = 10;
        int val = Add(2, 3) + x;
        Console.WriteLine("val={0}", val);

        static int Add(int a, int b)
        {
            return a + b;
        }
    }
}

出力結果

val=15

上記コード中では、7行目で宣言されている変数xを11~14行目で定義されてるAddの中で使用するとエラーになります。つまり下記のようにするとエラーです。

これはエラー

        static int Add(int a, int b)
        {
            x = 1;
            return a + b;
        }

ただし下記コードのように、ローカル関数Addの中で新たに親メソッドと同じ名前の変数xを宣言するのはOKです。この場合、変数xはローカル関数の中でのみ有効で、親メソッドの変数xとは別物です。このように親メソッドと同じ名前の変数をローカル関数内で宣言できるのはC# 8.0からです。この機能を変数のシャドーイングと言います。

これはOK

        static int Add(int a, int b)
        {
            int x = 1;
            return a + b;
        }

終わりに

ローカル関数はメソッドのほかに、

  • コンストラクタ
  • プロパティアクセサ
  • イベントアクセサ
  • 匿名メソッド
  • ラムダ式
  • ファイナライザ
  • ローカル関数

の中で定義できますので、機会があれば使ってみましょう。

ABOUT ME
しかすけ
日々是好日。何とか何とか生きてます。

COMMENT

メールアドレスが公開されることはありません。 が付いている欄は必須項目です