C# 8.0에 새롭게 추가된 문법으로 switch 식
이 있습니다.
저 같은 경우는 switch 식을 현재 업무에 열심히 적용하고 있는데요.
switch 식은 무엇이고 어떻게 사용하면 좋은지 예제와 함께 알아보겠습니다.
switch 식이란?
switch 식이란 원래 저희가 사용하던 switch 문을 좀 더 간결하게 사용하는 방식이라 생각합니다.
예제 코드를 통해 바로 확인해보면 아래와 같습니다.
switch 문 vs switch 식
특정 객체의 상태(EstateType)을 문자열로 바꿔주는 메소드가 있을 때 메소드 구현에 switch 문을 사용한다면 아래와 같습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public enum EStateType
{
EST_Idle,
EST_Running,
EST_Walk,
EST_Died,
}
// switch 문
public string GetStateEnumToString(EStateType type)
{
switch (type)
{
case EStateType.EST_Idle:
return "Idle";
case EStateType.EST_Running:
return "Running";
case EStateType.EST_Walk:
return "Walk";
case EStateType.EST_Died:
return "Died";
default:
return null;
}
}
이를 switch 식으로 바꾸면 아래와 같습니다.
1
2
3
4
5
6
7
8
9
10
11
// enum 생략
// switch 식
public string GetStateEnumToString(EStateType type) => type switch
{
EStateType.EST_Idle => "Idle",
EStateType.EST_Running => "Running",
EStateType.EST_Walk => "Walk",
EStateType.EST_Died => "Died",
_ => null
};
switch 식으로 바꿈으로써 훨신 간결해진 것을 볼 수 있습니다.
이 외에도 switch 문에 사용할 수 있는 여러 C# 문법들(Ex. 케이스 가드)도 switch 식에 사용이 가능함으로 적절하게 섞어서 사용할 수 있습니다.
switch 활용 방법
개인적으로 활용하고 있는 방식을 설명하고 있습니다.
꼭 정답은 아니며 이렇게 사용할 수 있구나 정도로 봐주시면 감사하겠습니다.(더 좋은 방법이 있다면 댓글로 남겨주세요!)
1. Getter
저 같은 경우는 C# 특성 상 메소드를 const
로 만들 수 없기 때문에 Getter를 만들 때 구현부에서 값 수정이 없다는 걸 직관적으로 보여주기 위해 람다 표현식을 자주 사용합니다.
만약 람다 표현식을 사용하지 않고 Getter를 만든다면 어떻게 될까요?
1
2
3
4
5
6
7
string name;
public string GetName()
{
name = "값 바꾸기";
return name;
}
GetName() 메소드에서 name 변수의 값을 바꾸는 행위가 있음에도 이를 알아차리기 쉽지 않습니다.
물론 값 수정이 필요할 때도 있습니다.(Ex. DB 데이터에서 특정 값을 반환하는 메소드)
그러므로 람다 표현식을 사용하면 Getter의 기능만 가지고 있는 메소드를 구현할 수 있습니다.
1
2
3
4
string name;
// 람다 식으로 간결하게 작성되어 있어 Getter 역할만 하는 것을 알 수 있습니다.
public string GetName() => name;
람다 표현식으로 구현된 Getter를 왜 사용하는지 충분한 설명이 되었다고 생각합니다.
하지만 이렇게 좋은 람다 표현식으로 구현된 Getter도 단점이 있는데요. 바로 조건식을 통한 분기문을 구현할 수 없다입니다.
그러므로, 형 변환이 필요한 Getter 같은 메소드는 람다 표현식으로 구현할 수 없는데요.
이를 가능하게 하는 것이 바로 switch 식입니다.
1
2
3
4
5
6
7
8
9
// switch 식
public string GetStateEnumToString(EStateType type) => type switch
{
EStateType.EST_Idle => "Idle",
EStateType.EST_Running => "Running",
EStateType.EST_Walk => "Walk",
EStateType.EST_Died => "Died",
_ => null
};
switch 식을 통해 해당 메소드가 Getter의 역할만 하고 있음을 보여주고 있고 분기를 통해 여러 값들을 반환하고 있다는 걸 볼 수 있습니다.
즉, switch 식을 통해 조건식이 추가된 안전한 Getter를 구현할 수 있게 되었습니다.
2. 전달 인자(argument)에 사용하기
개발을 하다 보면 전달 인자 값에 형변환이 필요할 때가 있습니다.
이 때 델리게이트나 확장 메소드 등을 사용해서 형변환 메소드를 구현할 수 있지만 switch 식을 이용해서도 구현이 가능해졌습니다.
예를 들어,
캐릭터를 구현한 Character 클래스와 애니메이션을 관리하는 AnimationComponent 클래스가 있다고 가정해보겠습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
class AnimationComponent
{
public enum EAnimType
{
EAT_Idle,
EAT_Running,
EAT_Walk,
EAT_Died,
}
public void SetAnimationState(EAnimType type)
{
// 이하 생략
}
}
class Character
{
public enum EStateType
{
EST_Idle,
EST_Running,
EST_Walk,
EST_Died,
}
EStateType _stateType;
public EStateType GetState() => _stateType;
}
이 때 character의 상태에 따라 Animation State를 바꿔줘야 하는 기능을 구현해야 한다고 할 때 switch 식 없이는 아래와 같이 구현할 수 있습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Character character = new();
AnimationComponent animation = new();
// Func을 통한 형변환 구현
Func<Character.EStateType, AnimationComponent.EAnimType> charStateToAnimState = (Character.EStateType state) =>
{
switch (state)
{
case Character.EStateType.EST_Running:
return AnimationComponent.EAnimType.EAT_Running;
case Character.EStateType.EST_Walk:
return AnimationComponent.EAnimType.EAT_Walk;
case Character.EStateType.EST_Died:
return AnimationComponent.EAnimType.EAT_Died;
default:
return AnimationComponent.EAnimType.EAT_Idle;
}
};
animation.SetAnimationState(charStateToAnimState(character.GetState()));
구현 자체는 가능하나 델리게이트를 구현하거나 메소드를 구현하거나 코드가 복잡해지고 길어지게 됩니다.
이 때 switch 식을 사용하면 간단하게 구현할 수 있습니다.
1
2
3
4
5
6
7
8
9
10
11
Character character = new();
AnimationComponent animation = new();
// switch 식을 통해 형변환을 구현
animation.SetAnimationState(
character.GetState() switch {
Character.EStateType.EST_Walk => AnimationComponent.EAnimType.EAT_Walk,
Character.EStateType.EST_Running => AnimationComponent.EAnimType.EAT_Running,
Character.EStateType.EST_Died => AnimationComponent.EAnimType.EAT_Died,
_ => AnimationComponent.EAnimType.EAT_Idle
});
switch 식을 통해서 코드가 간결하고 직관적으로 변한 걸 볼 수 있습니다.
요약
- switch 식을 통해 코드를 좀 더 간결하게 사용할 수 있다.
- Getter를 구현할 때 switch 식을 통해 분기식을 구현할 수 있다.
- 전달 인자(argument)에 형변환이 필요할 때 switch 식을 통해 간결하게 구현할 수 있다.