この記事では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;
}終わりに
ローカル関数はメソッドのほかに、
- コンストラクタ
- プロパティアクセサ
- イベントアクセサ
- 匿名メソッド
- ラムダ式
- ファイナライザ
- ローカル関数
の中で定義できますので、機会があれば使ってみましょう。

