25. try/finally 스택 되감기와 예외 필터(when)의 실행 시점 차이

난이도 최상 해설 보기 →

결함을 모두 찾고 원인·수정안·더 나은 설계를 제시하라. 마커 (A)(B) 는 주목 위치 힌트다.

결함 코드 · C#
// 문제 25 — try/finally 스택 되감기와 예외 필터(exception filter)의 실행 시점
//
// 아래 코드는 네트워크 패킷 처리 파이프라인에서 예외를 로깅하는 코드다.
// catch (Exception e) when (조건) 형태의 예외 필터를 사용해 특정 조건일 때만
// 예외를 잡도록 했고, finally 블록에서 리소스 정리 로그를 남긴다.
//
// (A) LogAndCheck(e) 가 예외 필터 조건식 안에서 호출된다.
// (B) finally 블록은 ProcessPacket 안에 있다.
//
// 과제:
// 1. 아래 프로그램을 실행하면 콘솔에 어떤 순서로 로그가 출력되는지 정확한
//    순서를 예측하라. 특히 "[finally] 패킷 처리 종료"와 "[filter] 필터 평가"와
//    "[catch] 예외 처리"의 상대적 순서를 명시하라.
// 2. 예외 필터의 조건식(when 뒤의 식)이 평가되는 시점이 스택 되감기(stack
//    unwinding) 이전인지 이후인지 설명하고, 그로 인해 필터 평가 시점에
//    호출 스택이 어떤 상태로 보이는지 설명하라.
// 3. 만약 LogAndCheck 내부에서 Environment.StackTrace 또는 디버거로 콜스택을
//    확인한다면, catch 블록 내부에서 확인할 때와 비교해 어떤 차이가 있는지
//    설명하라.
// 4. 이 특성이 실무에서 어떻게 (의도적으로) 활용되는지, 혹은 어떤 부작용을
//    낳을 수 있는지(예: 필터 안에서 사이드이펙트가 있는 로직을 수행하면
//    finally가 아직 실행되지 않은 상태에서 그 로직이 실행됨) 설명하라.
//
// 아래 코드는 콘솔에서 컴파일·실행 가능하다.

using System;

class PacketProcessor
{
    static bool LogAndCheck(Exception e)
    {
        Console.WriteLine($"[filter] 필터 평가 중... (e={e.GetType().Name})");
        return e is InvalidOperationException;
    }

    static void HandlePacket(int packetId)
    {
        Console.WriteLine($"[handle] packet={packetId} 처리 시작");
        if (packetId == 1)
        {
            throw new InvalidOperationException("잘못된 패킷 형식");
        }
        Console.WriteLine($"[handle] packet={packetId} 처리 완료");
    }

    static void ProcessPacket(int packetId)
    {
        try
        {
            try
            {
                HandlePacket(packetId);
            }
            finally
            {
                Console.WriteLine("[finally] 패킷 처리 종료 (내부 리소스 정리)");
            }
        }
        catch (Exception e) when (LogAndCheck(e))
        {
            Console.WriteLine($"[catch] 예외 처리: {e.Message}");
        }
    }

    static void Main()
    {
        ProcessPacket(1);
    }
}
내 리뷰 · C#
내 답안 · 자동 저장

작성 후 위 해설 보기에서 모범 해설과 대조하세요.