Notice
Recent Posts
Recent Comments
Link
«   2026/04   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30
Tags
more
Archives
Today
Total
관리 메뉴

뭐라도 쓰겠지

25.03.28 / 패턴 매칭(Pattern Matching) 본문

프로그래밍

25.03.28 / 패턴 매칭(Pattern Matching)

김데피 2025. 3. 28. 16:00

C#에서 패턴 매칭은 주어진 개체(객체)의 타입, 속성, 형태 등을 검사하여 분기 로직을 단순화해 주는 기능이다. C# 7에서 도입된 이 기능은 이후 버전에서 꾸준히 확장되어, 조건문이나 switch 문에서 더욱 다양한 형태로 활용할 수 있게 되었다. 아래에서는 주요 패턴 매칭 기능들을 정리해보겠다.

 

is 패턴 식

  • 1. 기본 is 식
    • C# 7 이전에도 is 키워드는 주어진 객체가 특정 타입인지 검사하는 용도로 사용되었다. 그러나 C# 7부터는 is 키워드 뒤에 패턴을 적용해 결과를 새 변수에 바인딩(Binding)할 수 있게 되었다.
object obj = "Hello";

if (obj is string s)
{
    Console.WriteLine($"문자열로 캐스팅됨: {s}");
}
else
{
    Console.WriteLine("문자열이 아님");
}

obj is string s는 obj가 string 타입인 경우, s라는 새 변수에 할당해주는 패턴이다.

 

  • 2. 타입 패턴
    • C# 8 이상에서는 is 식 뒤에 조건을 더 붙이기도 쉽다. 예를 들어, 추가 조건과 함께 검사할 수 있다.
static string CheckLength(object obj)
{
    return obj switch
    {
        string s when s.Length > 5 => "길이가 6 이상인 문자열",
        string s                   => "길이가 5 이하인 문자열",
        _                          => "문자열이 아님"
    };
}

string s when s.Length > 5 구문에서 when 절을 사용해 추가 조건을 걸 수 있다.

 

 

switch식 패턴 매칭

C# 7 이전의 switch 문은 단순히 상수(숫자, 문자, enum 등)에 대한 분기만 허용했다. C# 7부터는 switch 문(그리고 이후 C# 8부터 switch 식)에서 다양한 패턴을 사용할 수 있다.

  • 1. switch 문에서의 패턴
switch (shape)
{
    case Circle c:
        Console.WriteLine($"원의 반지름: {c.Radius}");
        break;
    case Rectangle r:
        Console.WriteLine($"사각형의 너비, 높이: {r.Width}, {r.Height}");
        break;
    default:
        Console.WriteLine("알 수 없는 도형입니다.");
        break;
}

shape가 Circle 타입이면 c로 바인딩하고, Rectangle이면 r로 바인딩해서 각 속성에 접근한다.

 

  • 2. switch 식
    • C#8에서 추가된 switch 식은 기존 switch 문법보다 간결하게 쓸 수 있다.
var message = shape switch
{
    Circle c => $"원의 반지름: {c.Radius}",
    Rectangle r => $"사각형의 너비와 높이: {r.Width} {r.Height}",
    _ => "알 수 없는 도형입니다."
};

식(Expression)으로 작성하여 바로 값을 반환할 수 있어, 간단한 매핑 로직에서 매우 편리하다.

 

 

패턴의 종류

  • 1. 타입 패턴(Type Pattern)
    • is, case와 함께 타입을 체크하면서 변수를 바인딩한다.
if (obj is int number)
{
    // obj가 int 형이면 number라는 새 변수에 들어감
}

 

  • 2. 상수 패턴(Constant Pattern)
    • 값이 특정 상수와 일치하는지 검사한다.
static string CheckValue(int x)
{
    return x switch
    {
        0 => "값이 0입니다.",
        1 => "값이 1입니다.",
        _ => "0과 1이 아닌 값입니다."
    };
}

 

  • 3. 분리 패턴(Deconstruction Pattern)
    • 클래스/구조체의 Deconstructor를 사용하거나 튜플로 분해한 뒤, 개별 요소에 대해 패턴 매칭을 할 수 있다.
// Point 클래스 예시
public class Point
{
    public int X { get; }
    public int Y { get; }

    public Point(int x, int y) => (X, Y) = (x, y);

    public void Deconstruct(out int x, out int y)
    {
        x = X;
        y = Y;
    }
}

Point p = new Point(1, 2);

var result = p switch
{
    (0, 0) => "원점",
    (1, 2) => "특정 좌표 (1,2)",
    ( > 0, > 0 ) => "1사분면",
    _ => "그 외 좌표"
};

(1, 2)처럼 튜플 형태로 분해하여 각각을 상수, 비교 연산자, 또 다른 패턴 등으로 매칭할 수 있다. ( > 0, > 0 )는 관계 패턴에 해당한다.

 

  • 4. 속성 패턴(Property Pattern)
    • C# 8 이후로 클래스로부터 특정 속성(또는 자동 구현 프로퍼티)에 접근해 값을 검사할 수 있다.
var result = p switch
{
    { X: 0, Y: 0 } => "원점",
    { X: 1 } => "X는 1",
    _ => "기타"
};

객체 p의 X와 Y 속성이 각각 0, 0인지 확인한다. 이 때 { X: 0, Y: 0 } 형태로 객체의 속성 이름을 직접 써서 매칭한다.

 

  • 5. 관계 패턴(Relational Pattern)
    • C# 9에서 도입되었으며, 특정 비교 연산자(<, <=, >, >=)를 통해 값을 매칭한다.
static string CompareNumber(int num)
{
    return num switch
    {
        < 0 => "음수",
        0 => "0",
        > 0 and < 100 => "양수이지만 100 미만",
        >= 100 => "100 이상",
    };
}

and, or 등의 논리 패턴도 C# 9부터 지원한다.

 

  • 6. 논리 패턴(Logical Pattern)
    • and, or, not 키워드를 사용하여 여러 패턴을 결합하거나, 패턴을 부정할 수 있다.
static bool IsSmallPositiveEvenNumber(int x)
{
    // 0보다 크고, 10보다 작고, 짝수인가?
    return x is > 0 and < 10 and { } evenCandidate && evenCandidate % 2 == 0;
}

// or 패턴
static string ClassifyNumber(int x)
{
    return x switch
    {
        < 0 => "음수",
        0 => "0",
        > 0 and < 10 => "1~9 범위의 수",
        > 0 and < 100 => "10~99 범위의 수",
        100 or 200 => "100 혹은 200",
        not (100 or 200) => "100, 200이 아님",
    };
}

not 키워드는 특히 스위치 패턴에서 패턴이 아닌 경우의 분기를 작성하거나, 기존 조건을 뒤집을 때 유용하다.

 

 

예외 처리와 함께 쓰기

C# 8부터는 when 필터나 패턴 매칭을 이용해 예외 처리 구문에서 특정 조건만을 포착하는 예시가 가능해졌다.

try
{
    // ...
}
catch (Exception e) when (e is SomeSpecificException { SomeProp: 123 })
{
    // SomeProp이 123일 때만 처리
}
catch (Exception e)
{
    // 그 외의 예외 처리
}

 

 

정리하자면 패턴 매칭은 C# 코드에서 타입 체크 및 분기 처리 로직을 간결하고 명확하게 만들어 준다. is 패턴 식과 switch 패턴, 그리고 추가된 관계/논리/속성/분리 패턴 등을 조합하면 복잡한 조건도 훨씬 깔끔하게 표현할 수 있다. C# 버전이 올라갈 수록 패턴 매칭 구문이 점점 풍부해지고 있으므로, 버전에 따른 차이점을 살펴보고 사용하는 것이 중요하다.

 

패턴 매칭은 한 번 익혀 놓으면 다양한 상황에서 로직 가독성을 높여 주는 강력한 도구이므로, switch식 또는 is 패턴 식을 언제 어떻게 활용할 수 있는지 많이 시도해보길 권장한다.