Computer >> 컴퓨터 >  >> 프로그래밍 >> C#

C# 7.0 패턴 매칭(Pattern Matching) 완벽 정리 - is 표현식과 switch 문 활용법

C# 7.0에서 도입된 패턴 매칭(Pattern Matching)은 코드의 가독성과 간결성을 크게 향상시키는 강력한 기능입니다. 이 기능은 is 표현식과 switch 문 두 곳에서 사용할 수 있습니다.

패턴 매칭의 핵심 개념

패턴은 값이 특정 형태(shape)를 가지고 있는지 검사하고, 일치하는 경우 해당 값에서 필요한 정보를 추출할 수 있습니다. 주요 특징을 정리하면 다음과 같습니다.

  • 간결한 문법: 복잡한 알고리즘을 더 짧고 읽기 쉬운 코드로 표현할 수 있습니다.
  • 모든 데이터 타입 지원: 직접 만든 사용자 정의 타입을 포함해 어떤 데이터 타입에도 패턴 매칭을 적용할 수 있습니다. 반면 기존의 if/else 방식은 기본 타입(primitive) 위주로만 매칭이 가능했습니다.
  • 값 추출 기능: 조건 검사와 동시에 표현식에서 값을 추출하여 변수에 바인딩할 수 있습니다.

패턴 매칭 이전의 코드

패턴 매칭이 없던 시절에는 is로 타입을 확인한 뒤, as 연산자로 다시 형변환을 해야 했습니다. 이 과정에서 코드가 중복되고 번거로워집니다.

예제 코드

public class PI{
    public const float Pi = 3.142f;
}
public class Rectangle : PI{
    public double Width { get; set; }
    public double height { get; set; }
}
public class Circle : PI{
    public double Radius { get; set; }
}
class Program{
    public static void PrintArea(PI pi){
        if (pi is Rectangle){
            Rectangle rectangle = pi as Rectangle;
            System.Console.WriteLine("Area of Rect {0}", rectangle.Width * rectangle.height);
        }
        else if (pi is Circle){
            Circle c = pi as Circle;
            System.Console.WriteLine("Area of Circle {0}", Circle.Pi * c.Radius * c.Radius);
        }
    }
    public static void Main(){
        Rectangle r1 = new Rectangle { Width = 12.2, height = 33 };
        Rectangle r2 = new Rectangle { Width = 12.2, height = 44 };
        Circle c1 = new Circle { Radius = 12 };
        PrintArea(r1);
        PrintArea(r2);
        PrintArea(c1);
        Console.ReadLine();
    }
}

실행 결과

Area of Rect 402.59999999999997
Area of Rect 536.8
Area of Circle 452.44799423217773

위 코드를 보면 is로 타입 검사를 한 후, as로 한 번 더 캐스팅하는 이중 작업이 발생합니다. 실수로 캐스팅을 누락하면 null 참조 오류가 생길 수도 있습니다.

패턴 매칭 적용 후의 코드

C# 7.0의 패턴 매칭을 사용하면 is 표현식 안에서 타입 검사와 변수 선언이 동시에 이루어집니다. 불필요한 as 캐스팅이 사라지고 코드가 훨씬 깔끔해집니다.

예제 코드

public class PI{
    public const float Pi = 3.142f;
}
public class Rectangle : PI{
    public double Width { get; set; }
    public double height { get; set; }
}
public class Circle : PI{
    public double Radius { get; set; }
}
class Program{
    public static void PrintArea(PI pi){
        if (pi is Rectangle rectangle){
            System.Console.WriteLine("Area of Rect {0}", rectangle.Width *
            rectangle.height);
        }
        else if (pi is Circle c){
            System.Console.WriteLine("Area of Circle {0}", Circle.Pi * c.Radius *
            c.Radius);
        }
    }
    public static void Main(){
        Rectangle r1 = new Rectangle { Width = 12.2, height = 33 };
        Rectangle r2 = new Rectangle { Width = 12.2, height = 44 };
        Circle c1 = new Circle { Radius = 12 };
        PrintArea(r1);
        PrintArea(r2);
        PrintArea(c1);
        Console.ReadLine();
    }
}

실행 결과

Area of Rect 402.59999999999997
Area of Rect 536.8
Area of Circle 452.44799423217773

핵심 차이점 비교

  • 기존 방식: if (pi is Rectangle)pi as Rectangle (검사와 캐스팅 분리)
  • 패턴 매칭 방식: if (pi is Rectangle rectangle) (검사와 선언을 한 줄로 처리)

두 예제 모두 동일한 결과를 출력하지만, 패턴 매칭 버전이 코드량이 줄고 의도가 명확하게 드러납니다. 또한 컴파일러가 타입 안전성을 보장하므로 런타임 오류 가능성도 낮아집니다.

마무리

C# 7.0의 패턴 매칭은 타입 검사와 값 추출을 하나의 표현식으로 통합하여 개발자의 생산성을 높여줍니다. 이후 C# 8.0, 9.0으로 버전이 올라가면서 switch 표현식, 관계형 패턴, 논리 패턴 등 더욱 강력한 패턴 매칭 기능들이 추가되었으니, 기초 개념을 잘 익혀두면 최신 C# 문법을 활용하는 데 큰 도움이 됩니다.