티스토리 뷰
3) 캐스트보다는 is, as가 더 좋다
C#은 정적 타이핑을 수행하는 언어다. 따라서 타입이 일치하지 않더라도 컴파일러가 컴파일타임 에러를 잡아주기 때문에 타입 검사를 자주해줄 필요는 없다. 하지만 코딩을 하다보면 형변환을 수행해야할 경우가 생긴다.
(정적 타이핑에 대한 간단한 소개는 다음 링크를 참조해주었으면 한다
- https://devmas.tistory.com/entry/%EB%8F%99%EC%A0%81%ED%83%80%EC%9D%B4%ED%95%91
- https://itmining.tistory.com/65)
형변환을 하는 방법은 캐스트 연산자 구문을 사용하는 방법, as 연산자를 사용하는 방법이 있으며 더 방어적으로 형변환을 하고 싶다면 is 연산자를 사용하여 형변환이 가능한지를 확인한 후에 형변환을 수행하도록 코드를 작성할 수 도 있다.
결론부터 말하자면, 캐스팅을 사용하는 것보단 as 연산자를 사용하는 것이 좋다. as 연산자를 사용하는 방법이 더 안전하고 성능면에서도 런타임에 더 효율적으로 동작한다. 하지만 캐스팅과 as 연산자가 형변환을 수행한다는 역할은 같을지라도 동작 방법은 차이점이 있는데 이를 잘 인지하고 사용해야 예상하지 못한 에러를 방지할 수 있다.
우선 as 연산자와 캐스팅이 어떤 차이점을 가지고 있는지부터 알아보자.
as 연산자와 캐스팅간의 차이
as 연산자와 캐스팅의 가장 큰 차이는 사용자 정의 형변환을 다루느냐 다루지 않느냐하는 점이다.
as 연산자는 임의의 객체를 원하는 타입으로 형변환할 경우, 지정한 타입이거나 혹은 지정한 타입을 상속한 타입이어야 한다. 그 외의 경우에는 전부 null을 반환하게 된다. 형변환을 받는 객체가 지정한 타입으로 사용자 정의 형변환이 정의되어 있더라도 무시한다는 말이다.
캐스팅의 경우엔 객체를 지정한 타입으로 형변환하기 위해 사용자 정의 형변환이 개입될 수 있다. 대표적인 형변환 연산자는 value 타입에서 숫자 간의 형변환 연산자다. ex) short ↔ long
그렇다면 이제 as 연산자가 캐스팅에 비해 어떤 장점을 가지고 있는지 알아보자.
as 연산자의 장점
1. 작성하기도 쉽고 읽기 편하다.
아래 코드를 보면 as를 사용하면 단 한 줄로 형변환되고 글을 읽듯이 코드가 읽히는 것을 볼 수 있다.
2. try/catch 문이 없기 때문에 성능이 좋다.
try/catch 문이 많아지면 성능에 악영향을 끼치게 된다.
아래 코드를 보고 캐스팅 방법은 as 연산자 방법과는 달리 null 체크를 해줄 필요 없지 않느냐고 반문할 수 있다. 하지만 실제로 캐스팅 방법을 사용할 때, null은 어떤 타입으로도 형변환이 가능하기 때문에 반환값이 null인지 따로 체크해줘야 하기 때문에 아래 코드에서 null 체크 코드를 따로 추가해줘야 한다.
3. 반환값 예상이 쉽다.
캐스팅의 경우엔 형변환을 수행할 때, 형변환 연산자가 개입할 가능성이 있어 반환값 예상이 다소 어려울 수 있다.
하지만 as 연산자의 경우에는 지정한 타입과 지정한 타입을 상속한 타입이 아닌 경우에는 전부 null을 반환하기 때문에 반환값 예상이 간편하다.
as 연산자를 사용할 수 없는 경우
그렇다면 as 연산자를 사용할 수 없고 캐스팅을 사용해야 할 경우를 알아보자.
as 연산자는 형변환을 할 수 없는 경우, null을 반환한다고 하였다. 하지만 int와 같은 value 타입의 객체들은 null을 가질 수 없는 타입이다. 이럴 경우, 캐스팅 구문과 예외 처리 방법을 통해 해결할 수도 있겠지만, 그보다 as 연산자를 그대로 사용하되 nullable 타입으로 형변환을 수행한 후 그 값이 null인지를 확인하는 편이 더 낫다. (아래 코드 참조)
객체 지향 프로그래밍에서는 형변환은 가능하면 피하는 것이 좋다고 한다. 하지만 간혹 형변환이 필요할 때도 있다. 이 경우에는 캐스팅보다는 개발자의 의도를 잘 표현할 수 있는 as와 is 연산자를 사용하자. 형변환하기 위해 캐스팅을 사용해야 할 때도 있다. 따라서 형변환할 때, 캐스팅과 as, is 연산자가 어떻게 동작하는지에 대해서 잘 알아둘 필요가 있다.
역시나 Java를 하다가 C#을 하면서 형변환하는 데 사용하는 as, is와 캐스팅과의 차이점을 알지 못 하고 쓰다가 이렇게 알게 되니 사이다를 마시는 기분이 든다. 역시 배우고 볼 일이다.
참고 - Effective C# <강력한 C# 코드를 구현하는 50가지 전략과 기법, 이펙티브>, 빌 와그너, 김명신, 한빛미디어
'Programming > Effective C#' 카테고리의 다른 글
[Effective C# Item 6] nameof() 연산자를 적극 활용하라 (0) | 2020.10.18 |
---|---|
[Effective C# Item 5] 문화권별로 다른 문자열을 생성하려면 FormattableString을 사용하라 (0) | 2020.10.18 |
[Effective C# Item 4] string.Format()을 보간 문자열로 대체하라 (0) | 2020.10.18 |
[Effective C# Item 2] const보다는 readonly가 좋다 (0) | 2020.10.18 |
[Effective C# Item 1] 지역변수를 선언할 때는 var를 사용하는 것이 낫다 (0) | 2020.10.18 |