패턴매칭과 switch case 중 어느게 더 효율적일까요??

아래 패턴매칭에 대한 얘기가 오고 가고 해서 이런 경우는 어떤가 해서 한번 의견을 들어 보고 싶습니다.

switch case 문을 패턴매칭으로 하였을 경우 어떤게 더 효율적이고 좋은 코드 일까요?


1. switch case 의 경우 

switch(error)
{
    case 0 : MessageBox.Show("ErrorMessage-1", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);  break ;
    case 1 : MessageBox.Show("ErrorMessage-2", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);  break ;
    default : MessageBox.Show("Unknown Error", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);  break ;

}
2. 패턴매칭을 사용했을 경우 

MessageBox.Show(ErrorMessage(error), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);

string ErrorMessage(int Error) => Error switch
{
        0 => "Error Message-1",
        1 => "Error Message-2",
         _ => "Unknown Error"
} ;
1 Like

보여 주신 코드로만 판단하면, 효율성 보다 더 중요한 차이가 있습니다.

1 번의 switch case 문은 분기와 I/O 호출이 한 덩어리로 묶여 있습니다.

이러한 코드를 포함한 메서드는 테스트가 불가능하고, MessageBox 가 존재하지 않는 컨텍스트에는 코드 재사용도 불가능하고, 전역 변수에 접근하기 때문에 동시성 문제도 있습니다.

그에 반해, 2번의 경우, 독립적으로 테스트 가능하고, 동시성 문제도 없으며, 재사용 가능한 코드입니다.

한 가지 더 언급하고 싶은 부분은 ErrorMessage(int Error)의 호출자는 Error 에 어떤 값을 할당해야 하는 지에 대한 정보가 전혀 없습니다.

즉, 작성자만 알 수 있는 readonly code라 할 수 있는데, 그 원인은 추상화 부족입니다. Error 에 강력한 형식을 부여한다면, 이 문제를 해결할 수 있습니다.

enum Error { Error1, Error2 }
// 혹은
abstract record Error;
record Error1 : Error;
record Error2 : Error;
static class ErrorExt
{
    public static string ErrorMessage(this Error error) => error switch
    {
        Error1 => "Error 1 occurred",
        Error2 => "Error 2 occurred",
        _ => "Unknown error" // enum 인 경우 없어도 됨.
    };    
}
6 Likes

패턴매칭보단… switch 문과 switch 식 아닌가요?

4 Likes

스위치 문도 패턴매칭으로 바꾸자는 제안이 올라와 있습니다. :rofl:

2 Likes
switch(error)
{
    case 0: errMsg = "ErrorMessage-1";  break ;
    case 1: errMsg = "ErrorMessage-2";  break ;
    default: errMsg = "Unknown Error";  break ;
}
MessageBox.Show(errMsg, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);

switch문이 좀 억울해 보여서 이런식으로 고쳐야 할 것 같아요