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# 문법을 활용하는 데 큰 도움이 됩니다.