ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • C# 람다식 - 변수캡처
    C# 2022. 2. 20. 22:31
    728x90

    해당 문서는 길벗 출판사의 'C#을 다루는 기술'에 나온 소스를 정리하기 위해 만들었다.

    기본적인 람다식 문법은

    람다식 문법 : (입력 파라미터) => { 실행문장 블럭 };

    위와 같이 사용한다.

    가장 많이 사용하는 방식은 Linq를 제외하면

    Func<int, int, int> multiply = (x, y) => x * y;

    위와 같이 길어 질 수 있는 코드를 짧게 축약하기 위해 사용할 때 사용한다.

    단순히 짧게 만들어 델리게이트를 생성하는 건 좋지만

    변수 캡처

    변수 캡쳐

    여러가지 소스의 예제가 있고 설명이 있지만 한개만 기억하기위해 아래의 소스코드를 가져왔다.

    
    static List<Action> CreateCountingActions()
    {
        List<Action> actions = new List<Action>();
        int outerCounter = 0; // 두 개의 델리게이트에서 하나의 변수를 캡처
    
        for(int i = 0; i< 2; i++)
        {
            int innerCounter = 0; //루프 순회시마다 다시 0으로
            Action action = () =>  //아래의 actions[숫자]() 에서 바로 여기로 실행
            {
                Console.WriteLine(
                    $"Outer : {outerCounter}, inner : {innerCounter}"
                    );
                outerCounter++;
                innerCounter++;
            };
            actions.Add(action);
        }
        return actions;
    }
    
    List<Action> actions = CreateCountingActions(); // 생성하면서 for문을 돌며 List에 2개의 action 생성
    actions[0](); // Outer: 0; Inner: 0
    actions[0](); // Outer: 1; Inner: 1
    actions[1](); // Outer: 2; Inner: 0
    actions[1](); // Outer: 3; Inner: 1

    이걸 디버그 모드로 실행해 보자 actions[0]을 2번 실행하면 분면 CreateCountingActions에서 action을 실행하는데
    outer야 action이 실행될때마다. 증가하니 그려니 하지만 inner가 이상하다.
    for문을 거친게 아니라 바로 action을 디보그 모드에선 들어가는데 innerCounter숫자가 actions1을 실행시 innerCounter = 0이 실행되었다. 그럼 actions[0]과 actions[1]을 순서대로 실행해 보면 어떨까?

    actions[0](); // Outer: 0; Inner: 0
    actions[1](); // Outer: 1; Inner: 0
    actions[0](); // Outer: 2; Inner: 1
    actions[1](); // Outer: 3; Inner: 1

    위와 같이 Outer는 그대로 증가하고 Inner는 0,0,1,1 이 나온다.

    즉 for문 안에서 생성한 것은 바깥에서 생성한 것의 값을 참조는 하고 있지만 for문 안에서 action을 등록시에 생성하고 있다는 것을 알 수 있다.
    별로 쓰이지 않는 상황이라고는 하지만 어떻게 실행되는지만이라도 기억해 두자.

    728x90
    반응형

    댓글

Designed by Tistory.