확장 속성 패턴(Extended Property Pattern)

황현중·2025년 12월 11일

1. 먼저, “속성 패턴(Property Pattern)”이 뭔지부터

속성 패턴은 객체의 속성 값을 기준으로 매칭하는 패턴 매칭 문법이다.

if (order is { Status: "Closed", Amount: > 0 })
{
    Console.WriteLine("종료된 유효 주문");
}

위 코드는 이렇게 읽을 수 있다.

  • order라는 객체가 있고,
  • 그 안에 Status 속성이 있고 값이 "Closed"이고,
  • Amount 속성이 있고 값이 0보다 크면,
  • if 블록 안으로 들어간다.

즉,

order.Status == "Closed" && order.Amount > 0

를 패턴 매칭 문법으로 예쁘게 표현한 것이라고 보면 된다.
여기까지가 기본적인 속성 패턴이다.


2. 중첩된 객체일 때 기존 속성 패턴은 어떻게 생겼나?

이제 이런 모델을 가정해 보자.

class Address
{
    public string City    { get; set; }
    public string Country { get; set; }
}

class Person
{
    public string Name    { get; set; }
    public Address Address { get; set; }
}

Person 안에 Address가 있고, 그 안에 다시 City가 있는 구조다.
이때 “서울에 사는 사람”을 체크하고 싶다고 하자.

2-1. C# 10 이전 스타일 (중첩 속성 패턴)

if (person is { Address: { City: "Seoul" } })
{
    Console.WriteLine("서울에 사는 사람");
}

읽어보면:

  • person
    • Address라는 속성을 가지고 있고,
    • Address 속성 안에 City라는 속성이 있고,
    • 그 값이 "Seoul"이면 매칭된다.

동작은 이해되는데, 괄호가 겹겹이 중첩되어 있어서 눈에 잘 안 들어오고, 우리가 평소에 쓰는 person.Address.City 스타일과도 조금 거리가 있다.


3. 확장 속성 패턴(Extended Property Pattern) 등장

이런 불편함 때문에 C# 10부터 확장 속성 패턴이라는 문법이 추가되었다.
핵심 아이디어는 아주 단순하다.

“중첩 객체의 속성도 Address.City처럼 점(.)으로 이어서 쓸 수 있게 하자.”

3-1. 같은 의미, 더 간단한 문법

// 옛날 방식
if (person is { Address: { City: "Seoul" } }) { ... }

// 확장 속성 패턴
if (person is { Address.City: "Seoul" }) { ... }

둘은 완전히 동일한 의미다. 다만 확장 속성 패턴은:

  • Address 속성 안으로 들어가서
  • 그 안에 있는 City를 바로 지정할 수 있도록

“점(.)으로 경로를 확장해서 쓰는 속성 패턴” → Extended Property Pattern 이라고 부른다.


4. 확장 속성 패턴 예제 모음

4-1. City + Country 동시에 체크하기

기존 방식:

if (person is { Address: { City: "Seoul", Country: "KR" } })
{
    Console.WriteLine("한국 서울 거주자");
}

확장 속성 패턴으로 쓰면:

if (person is { Address.City: "Seoul", Address.Country: "KR" })
{
    Console.WriteLine("한국 서울 거주자");
}

동작은 똑같지만, Address.City, Address.Country처럼 평소에 쓰던 프로퍼티 접근 방식과 거의 같아서 훨씬 읽기 편하다.

4-2. 속성 패턴 + switch 식

string Describe(Person p) => p switch
{
    { Address.City: "Seoul", Address.Country: "KR" }
        => "서울에 사는 한국인",

    { Address.Country: "KR" }
        => "한국에 사는 사람",

    { Address.Country: "US" }
        => "미국에 사는 사람",

    _   => "그 외"
};

원래라면 전부 { Address: { City: ..., Country: ... } } 형태로 썼어야 한다.
확장 속성 패턴 덕분에, 우리가 평소에 생각하는 p.Address.City, p.Address.Country 느낌을 그대로 패턴 안에서도 사용할 수 있게 된 것이다.


5. 확장 속성 패턴 정리

5-1. 개념 요약

  • 기본 속성 패턴
    • obj is { Prop: value, OtherProp: > 0 }
    • → 객체의 프로퍼티 값에 따라 매칭
  • 확장 속성 패턴 (Extended Property Pattern)
    • 중첩 객체에서도 Address.City처럼 점(.)으로 바로 접근
    • obj is { Address.City: "Seoul" }
    • { Address: { City: "Seoul" } }와 동등한 표현

5-2. 장점

  • 가독성 향상
    • 중첩 중괄호를 줄여서 눈에 잘 들어온다.
    • 일반 C# 코드의 obj.Address.City와 사고방식이 거의 동일하다.
  • 복잡한 조건을 패턴 하나로 표현 가능
    • if-else로 늘어지던 조건을 switch + 패턴으로 깔끔하게 정리하기 좋다.

6. 언제 써보면 좋을까?

  • DTO / ViewModel 등이 중첩 구조를 가질 때
    • 예: Order.Customer.Grade, Order.Shipping.Address.City
  • 상태 분기를 switch 식으로 깔끔하게 정리하고 싶을 때
  • “조건문 지옥”이 되어 있는 코드를 리팩터링하면서
    • if (p.Address != null && p.Address.City == "Seoul") ...
    • 같은 코드를 패턴 매칭 기반으로 바꿔보고 싶을 때

7. 한 줄 요약

확장 속성 패턴(Extended Property Pattern)은 “중첩 객체의 속성을 패턴 매칭에서 Address.City처럼 점(.)으로 편하게 표현하는 문법”이다. 기존 { Address: { City: ... } } 를 더 읽기 쉬운 형태로 줄여준다고 생각하면 된다.

0개의 댓글