C# 함수 안에서 함수 선언하기 (C# Function inside a function)

  루아, 루비, F# 등등 수많은 언어에는 함수 안에서 함수를 선언할 수 있는 기능이 있습니다. 예를 들어 루아의 경우 아래와 같이 간단하게 함수 안에서 함수를 선언할 수 있죠.

function MainFunction()
 -- LOGIC
 local function Print = function(str)
  print(str)
 end
end


  하지만 C#에서 아래와 같이 코딩을 한다면 에러가 나게 됩니다.
public static void Main(string[] args)
{
    void Print(string a)
    {
        Console.WriteLine(a);
    }
}


  그렇다면, C#에선 함수 안에서 함수를 선언하기란 불가능한 것일까요? 만약 그랬다면 제가 이 글을 쓰고 있지 않겠죠. 당연히 방법은 있습니다. Action 대리자와 Func 대리자를 사용하시면 됩니다.

Action 대리자

  Action 대리자는 함수에 반환값이 없을 때 사용합니다. 즉, 어떤 함수 내부에 void형 함수를 선언하고 싶을 땐 Action 대리자를 사용하시면 됩니다.
  Action 대리자의 선언부에선 최대 16개의 요소가 인수의 형식으로 지정됩니다.
public static void Main(string[] args)
{
    Action PrintMessageRepeat = (message, count) =>
    {
        for (int i = 0; i < count - 1; i++)
        {
            Console.Write(message);
        }
    }

    PrintMessageRepeat("안녕! ", 3);
}
// 결과: ["안녕! 안녕! 안녕!"]


Func 대리자

  Func대리자는 함수에 반환값이 있을 때 사용합니다. 즉, 어떤 함수 내부에 void형이 아닌, int, string, bool 등등 반환값을 가지는 함수를 선언하고 싶을 때 사용하시면 됩니다.
  Func대리자의 제네릭 선언부에선 맨 마지막 하나가 무조건 반환값이 되며, 그 전의 모든 요소는 전부 인수의 형식이 됩니다. 아래에선 입력으로 하나의 long 형식 값을 받고 long 형식 값을 반환하는 함수가 되겠군요.
public static void Main(string[] args) 
{
    Func Fibonacci = null;

    Fibonacci = (input) =>
    {
        if (input == 0)
        {
            return 0L;
        }
        if (input == 1)
        {
            return 1L;
        }
        return Fibonacci(input - 2) + Fibonacci(input - 1);
    };

    for (int i = 1; i < 20; i++)
    {
        Console.WriteLine(Fibonacci(i));
    }
}

댓글

  1. 만든 함수내에서만 호출가능한가요?
    다른 함수에서 호출해서 사용하려면 어떻게 해야하나요?
    궁금합니다. 알려주세요~

    답글삭제
    답글
    1. 당연히 Scope라는 것이 존재하기에 안쪽 스코프에서 생성된 대리자는 외부 스코프에서 호출할 수 없습니다. 다만, 대리자를 인수로 사용하는 메서드에 인자로 넘겨서 쓸 수는 있습니다.

      void Main(string[] args)
      {
      Func funcSum = (a, b) => a + b;

      OuterFuncCaller(10, 20, funcSum); // => 30
      }

      int OuterFuncCaller(int a, int b, Func deleFunc)
      {
      return deleFunc(a, b);
      }

      삭제

댓글 쓰기

이 블로그의 인기 게시물

C# 남아도는 메모리에도 불구하고 OutOfMemoryException이 발생한다면?

USB를 뒤는 괜찮은데 앞에 꽂으면 인식이 힘들다?

MySQL 데이터 타입과 Java 데이터 타입 비교/매칭