C# :: Lecture & TIPs

[C#] Pattern Matching (패턴 매칭) 에 대해 알아보자!

패턴이 있는 Is 표현식 (Is-expressions with patterns)

아래 예시를 보시면 상수 패턴과 (const pattern) 과 타입 패턴 (type pattern) 을 사용한 표현식을 확인하실 수 있습니다.

 public void PrintStars(object o)
 {
     if (o is null) return; // 상수 패턴 "null"
     if (!(o is int i)) return; // 타입 패턴 "int i"
     WriteLine(new string('*', i));
 }

위 예제를 보시면 패턴 변수라는 것이 등장하는데, 표현식 중간에서 패턴 변수를 선언하실 수 있고, 자신을 둘러싸고 있는 Code Block (코드 블록) 내에서 사용할 수도 있는 것을 확인하실 수 있을텐데요, C# 의 Inline Out Variables (인라인 아웃 변수) 와 유사합니다.

패턴을 Try 로 시작하는 Method (메소드) 와 함께 사용할 경우 아래와 같이 유용하게 사용하실 수도 있겠습니다.

if (o is int i || (o is string s && int.TryParse(s, out i)) { /* i 사용 */ }


패턴이 있는 Switch 문 (Switch statements with patterns)

C# 7.0 에서는 Switch 문에 기본 Type 뿐만 아니라 모든 Type 을 Pattern Matching (패턴 매칭) 에 사용할 수 있게 되었습니다. 일례로 case 절에서도 Pattern (패턴) 을 사용하실 수 있으며 아래와 같이 When 문을 통해 다른 조건을 추가할 수도 있도록 개선되었습니다.

case (expr) when (when-condition):

예시 코드를 직접 보면서 이해해보도록 합시다.

switch (shape)
{
    case Circle c:
        WriteLine($"반지름이 {c.Radius} 인 원");
        break;

    case Rectangle s when (s.Length == s.Height):
        WriteLine($"{s.Length} x {s.Height} 정사각형");
        break;

    case Rectangle r:
        WriteLine($"{r.Length} x {r.Height} 직사각형");
        break;

    default:
        WriteLine("<알 수 없는 모양>");
        break;

    case null:
        throw new ArgumentNullException(nameof(shape));
}

위의 예시에서 주의해야 할 점 몇 가지가 존재한다면 아래와 같습니다.

default 절은 항상 마지막에 검사합니다. 윗 예제와 같이 null 절이 마지막에 오는 경우라 할지마도 default 절 검사에 앞서 null 절을 먼저 검사합니다. 이는 기존의 switch 문과도 동일합니다.

마지막에 위치한 null 절에 도달하는 것은 불가능합니다. 암시적으로 null 검사가 존재하기 때문에 어떠한 형식의 Pattern (패턴) 이 먼저 오더라도 실수로 가로채는 사례를 방지해줍니다. 예를 들어, shape 값이 null 인 Circle (원형) 객체일 경우로 가정하면, 첫 번째에 있는 case 절이 먼저 확인한 후 c.Radius 에서 NullReferenceException 예외가 발생하는 경우를 방지해준다는 의미입니다.

기존의 switch 문을 사용할 때와 같이 순서가 중요합니다. 가령, shape 값이 정사각형인지 확인하는 case 절을 아래로 내려버리면 정사각형 임에도 불구하고 직사각형으로 판단하는 결과를 확인하실 수 있습니다. 개발자가 실수로 순서를 뒤바꿔서 코딩하더라도 Complier (컴파일러) 수준에서 이전 case 절에서 이미 처리되었다는 오류메시지를 표시합니다.

여기서 case … : label (레이블) 에 들어간 패턴 변수는 해당 switch 영역 범위에서만 사용할 수 있다는 것도 확인하실 수 있습니다.

Leave a Reply