[C# 8.0] Switch문, Switch식, 패턴 매칭(Pattern Matching)

Switch Statement

Switch문(Switch Statement)은 아래와 같이 패턴이 일치하는 case 블럭을 실행하도록 한다. 

void Test(string text)
{
	switch (text)
	{
		case "a": break;
		case "b": break;
		case "c": break;
	}
}

기존에는 bool, int, string, enum 등의 타입만 사용하여 분기처리를 할 수 있었으나

C# 7.0 부터는 다양한 패턴 매칭을 통해 분기처리를 할 수 있게 되었다.

 

상수 패턴(Constant pattern)

지정된 상수와 같은 값인지 체크한다. 상수 패턴에서 사용할 수 있는 형은 아래와 같다.

- int, 부동 소수점 숫자형 (float, double, decimal)

- char

- bool

- enum

- const

- null

 

타입 패턴(Type pattern)

is 키워드와 유사하게 주어진 객체와 같은 타입인지 확인하고, 맞다면 작업을 수행한다.

값이 null 일 경우에는 매칭 실패로 간주한다.

 

var 패턴 (Var pattern)

타입 패턴과 비슷해보이지만, var 패턴은 항상 매칭이 성공된 것으로 본다.

값이 null 일 경우에도 매칭 성공으로 간주하기 때문에, when 같은 가드절(case guards)과 함께 사용해야한다.

 

선언 패턴 (Declaration Pattern)

객체를 지정된 타입으로 변환하고, 성공했을 경우 변수에 변환된 결과가 할당된다.

변환된 결과를 사용할 수 있는 점 때문에 if문에 많이 사용한다.

void Test(object obj)
{
    switch (obj)    
    {
        // <-- 타입 패턴(Type Pattern)
        case Color c:
            break; 
            
        // when, is 사용
        case TestType t when t.value is > 0 or < 10:
            break;
            
        // string.IsNullOrEmpty, StartWith 등도 사용 가능
        case string s when s.Contains("test"):
            break;
        // -->
            
            
        // <-- var 패턴(Var pattern)
        case var v when v.Equals(10):
            break;
        // -->

            
        // <-- 상수 패턴(constant pattern) 
        case "test":
            break;
            
        case null:
            break;
        // -->
    }

    // <-- 선언 패턴
    object o = 2024;
    if (o is int num)
    {
        Console.WriteLine(num * 10);
    }
    // -->
}

 

 

Switch Expression

C# 8.0 부터는 Switch식(Switch Expression)을 사용할 수 있게 되었다.

case, break, default 등을 선언하지 않기 때문에 코드를 보다 간결하게 작성할 수 있으며, 분기 처리 보다 식 처리값의 반환이 필요할 때 사용하면 좋다.

int index = GetIndex();
string page = index switch
{
    int i when i <= 10          => "first",
    int i when 10 < i && i < 20 => "second",
    _                           => "third"
};

var test = new TestType { value = 10 };
string name = test switch 
{
    {value: < 10}           => "a",
    {value: >= 10 and < 20} => "b",
    _                       => "c"
};