[Unity]/[C#]

[C#] 캡처(Capture feat. 람다식)

극꼼 2022. 10. 12. 20:41
반응형


<람다식 구분>

  • 표현식 본문(Expresstion Lambda) : 본문의 코드를 한 줄로 단순화하여 쓴 경우
(input-parameters) => expression
  • 문장 본문(Statement Lambda) : 중괄호를 포함한 경우
(input-parameters) => { <sequence-of-statements> }

 


<캡처>

: 람다식으로 델리게이트 인스턴스를 생설할 때, 컴파일러는 람다식 내의 코드를 다른 메서드로 분리하여 생성합니다. 

  • 캡처
    • 람다식 내에서 사용되었지만, 람다식 외부에서 선언된 변수 = 캡처된 변수.
    • 람다식 자체의 매개변수, 람다식 내에서 선언된 지역 변수 = 캡처된 변수가 아님.

 

예시 코드)

public class Test2_
{
    private string instanceField = "instanceField";
    static public Action<string> CreateAction(string param)
    {
        string methodLocal = "methodLocal";
        string cap = "uncap";
        Action<string> action = lambdaParam => 
        {
            string lambdaLocal = "lambdaLocal"; 
            Console.WriteLine(instanceField);
            Console.WriteLine(methodLocal);
            Console.WriteLine(param);
        };
        methodLocal = "modifiedMethodLocal" + param;
        return action;
    }
}
  • 위의 클래스에서 캡처된 변수는 다음과 같습니다.
    • string instanceField
    • string param
    • string methodLocal

<컴파일러의 캡처 구현 방법>

1) 인스턴스 필드를 캡처 : 컴파일러는 인스턴스 메서드를 생성.

2) 지역변수, 매개변수를 캡처 : 컴파일러는 private로 중첩 클래스를 작성하고, 그 내부에 필요한 정보를 담도록 코드를 생성합니다. 그리고 그 클래스 내에 인스턴스 메서드를 추가합니다. 해당 지역, 매개변수에 접근하는 코드가 있을 경우 이 클래스를 사용하도록 수정해줍니다.

 

설명만 읽으면 이해가 어렵습니다. 위쪽의 예시 코드를 컴파일러가 재구성한 코드입니다.

private class LambdaContext // private로 캡처한 변수를 저장할 클래스 작성
{
    public Test2_ originalThis; 
    public string param;
    public string methodLocal;

    public void Method(string lambdaParam) 
    {
        string lambdaLocal = "lambdaLocal";
        Console.WriteLine(originalThis.instanceField);
        Console.WriteLine(methodLocal);
        Console.WriteLine(param);
    }
}

//메서드로 변형된 람다식
public Action<string> CreateAction(string param)
{
    LambdaContext context = new LambdaContext(); //캡처한 변수를 가져올 클래스 인스턴스 생성함
    context.originalThis = this;
    context.param = param;
    context.methodLocal = "methodLocal";
    string cap = "uncap";
    Action<string> action = context.Method;
    context.methodLocal = "modifiedMethodLocal" + param;
    return action;
}

 

 

 

반응형

'[Unity] > [C#]' 카테고리의 다른 글

[C#] is, as 연산자  (1) 2022.10.11
[C#] 제네릭(Generic)  (0) 2022.10.07
[C#] readonly 한정자 (feat.const 한정자)  (1) 2022.10.06
[C#] reflection  (0) 2022.10.05
[C#] partial 클래스  (0) 2022.10.04