영어로는 Local Functions라고 부르며, C# 7.0 버전부터 지원하기 시작한 기능입니다.
앞서 메서드 호출에 대해 배웠습니다. 메서드 코드 블록 안에서 다른 메서드를 호출할 수 있으며 규칙은 다음과 같습니다.
- 같은 클래스 내 메서드: 메서드 이름에 매개변수를 넘겨 직접 호출하면 됩니다.
- 다른 클래스의 메서드: 먼저 해당 클래스의 인스턴스를 생성해야 하고, 대상 메서드에는
public키워드를 붙여야 합니다.
C# 7.0부터 하나의 메서드 안에 독립적인 함수를 직접 정의할 수 있는데, 이것을지역 함수라고 부릅니다.
- 격리성: 감싸고 있는 외부 메서드 안에서만 호출할 수 있고 외부 코드는 접근할 수 없습니다.
- 장점: 관련 로직을 한 곳에 모을 수 있어 가독성이 좋고 유지보수가 쉬워집니다.
- 선언 규칙: 지역 변수와 달리 지역 함수는 외부 메서드 안 어디든 선언 가능하며 미리 선언하지 않아도 됩니다.
지역 함수는 외부 메서드의 지역 변수를 캡처할 수 있지만 범위는 자신을 감싼 메서드 내로 제한됩니다.
먼저 알아둬야 할 개념 하나를 보충하겠습니다.
함수 안의 지역 변수는 위에서 아래로 순서대로 실행됩니다. 변수를 사용하려면 먼저 선언해야 하며 순서를 바꿀 수 없습니다.
아래 코드를 예시로 살펴보죠. hour 변수는 아래쪽에서 생성되므로 선언 전에 접근할 수 없습니다.
int GetHours()
{
Console.WriteLine(hour);
int hour = DateTime.Now.Hour;
return hour;
}Code language: C# (cs)
hour의 범위가 메서드 전체에 걸치더라도 먼저 사용하고 나중에 선언하는 방식은 허용되지 않습니다.

붉은 물결 밑줄 오류가 발생하며 오류 메시지는 위 그림과 같습니다.
일반 함수와는 다릅니다. 아래쪽에 정의된 함수를 위쪽에서 호출할 수 있는 이유는 클래스 메서드가 클래스 멤버로서 Method Table(메서드 테이블)에 기록되기 때문입니다. 호출할 때 테이블을 조회하지 위에서 아래로 순차 실행하는 방식이 아닙니다.

아래 예시에서 위쪽 Main이 아래쪽 GetHours를 호출하는 모습을 볼 수 있는데, 이는 앞서 본 지역 변수 규칙과 다릅니다.
class Program
{
static void Main()
{
Program program = new Program();
program.GetHours();
}
int GetHours()
{
int hour = DateTime.Now.Hour;
return hour;
}
}Code language: C# (cs)
다시 지역 함수로 돌아가 보겠습니다.
예시 코드를 확인하세요.
class Program
{
static void Main()
{
Program program = new Program();
program.ZoomIn();
}
public void ZoomIn()
{
// 지역 함수가 선언되기 전에도 호출 가능
int results0 = ZoomIn5(10);
Console.WriteLine($"A: {results0}");
// 지역 함수: 전달받은 값 val을 5배로 늘려 반환
int ZoomIn5(int val)
{
return val * 5;
}
// 지역 함수 호출
int results = ZoomIn5(10);
Console.WriteLine($"B: {results}");
int results2 = ZoomIn5(5);
Console.WriteLine($"C: {results2}");
}
}
Code language: C# (cs)
지역 함수의 범위는 자신이 속한 메서드 내로 한정되며, 코드가 지역 함수 선언보다 위에 있든 아래에 있든 자유롭게 호출할 수 있습니다.
그리고 지역 함수 이름을 감싸고 있는 외부 메서드와 동일하게 지정하는 것도 가능합니다.
class Program
{
static void Main()
{
Program program = new Program();
program.ZoomIn5();
}
public void ZoomIn5()
{
// 지역 함수가 선언되기 전에도 호출 가능
int results0 = ZoomIn5(10);
Console.WriteLine($"A: {results0}");
// 지역 함수: 전달받은 값 val을 5배로 늘려 반환
int ZoomIn5(int val)
{
return val * 5;
}
// 지역 함수 호출
int results = ZoomIn5(10);
Console.WriteLine($"B: {results}");
int results2 = ZoomIn5(5);
Console.WriteLine($"C: {results2}");
}
}
Code language: C# (cs)
위 예시에서 외부 메서드와 내부 지역 함수 모두 ZoomIn5로 이름이 같습니다. 범위가 서로 다르므로 충돌하지 않지만, 이런 방식의 코딩은 권장하지 않습니다.
지역 함수