예시

case 1

public void Test1()
{
    Action print = delegate()
    {
        Console.WriteLine("A");
    };
    print();
}
  • print라는 delegate 객체에 무명 메서드를 정의하고 할당
  • 이것은 Closure가 아니다

case 2

public void Test2()
{            
    Action<string> print = delegate (string msg)
    {                
        Console.WriteLine(msg);
    };
    print("A");
}
  • print라는 delegate 객체에 파라미터(string msg)를 받는 무명 메서드를 정의하고 할당
  • 이것도 Closure가 아니다

case 3

public void Test3()
{
    int key = 10;

    Action<string> print = delegate (string msg)
    {
        string str = key + msg;
        Console.WriteLine(str);
    };

    print("A");  // 10A
}
  • delegate에 할당할 메서드의 외부 변수, Test3의 지역 변수인 key를 사용
  • 이것이 Closure의 예시

Clusore란?

  • 어떤 메서드가 있고, 그 메서드 안에서 무명 메서드나 람다식이 정의되어 있고 지역 변수가 선언되어 있다
    • 이 때 정의된 무명 메서드 혹은 람다식이 이 지역변수를 사용하면 이를 Clousre라 한다
  • 외부 함수에 접근할 수 있는 내부 함수 혹은 이러한 원리
    • 일반적으로 어떤 함수가 소멸하면서 스택 프레임이 해제되지만, 외부함수의 지역변수를 사용하는 내부 함수가 소멸할 때까지 외부함수는 소멸하지 않음
  • Lexcial scope내의 Free variable을 사용하는 일급함수(First-class function)
  • 함수가 Context를 보유할 수 있도록 한 기능
    • 여기서 Context는 Closure가 정의된 외부 함수의 변수들

일급함수

  • 다른 메서드/함수의 파라미터로 전달해서 사용할 수 있는 함수
  • C#에서의 무명메서드, 람다식 등
    • Action, Predicate, Func, delegate 등…

어디서 사용하는가?

  • 함수의 첫 정의 시점에서의 Context를 유지할 필요가 있을 때
class Class1
{
    private List<string> list = new List<string>()
    {
        "A", "AB", "ABC", "ABCD", "ABCDE"
    };

    public IList<string> GetList(int maxLength)
    {
        // Where에 할당되는 함수는 외부 변수인 maxLength를 사용
        // 아래 람다식은 Closure
        var limitedList = list.Where(p => p.Length <= maxLength).ToList();

        return limitedList;
    }
}

출처

Categories: ,

Updated: