캐스트보다는 is, as가 좋다.
[ Content ]
- cast (캐스트)
. 프로그래밍 언어에서, 객체의 유형을 다른 유형으로 바꾸는 것을 말한다.
. 아래는 C형태의 캐스트로 '(타입)피연산자' 형태로 사용된다.
| int i = 42; char* p = &buf; *p = (char)i; | cs
|
- as 연산자
. 특정 형식의 변환을 수행한다. 캐스트 작업과 비슷하지만, 변환할 수 없는 경우 예외를 발생시키지 않고 null을 반환한다.
. 참조 : https://docs.microsoft.com/ko-kr/dotnet/csharp/language-reference/keywords/as
- is 연산자
. 지정된 형식으로 변환할 수 있는지, 런타임에 형식 호환성을 평가한다.
변환이 가능하면 true, 그렇지 않으면 false를 반환한다.
. 참조 : https://docs.microsoft.com/ko-kr/dotnet/csharp/language-reference/keywords/is
- is, as 연산자를 사용하는 것이 좋은 이유!
1. 코드 작성이 용이하다.
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 | object o = Factory.GetObject(); //----------- as 연산자를 사용한 버전 MyType t = o as MyType; if(t != null) { // MyType 타입의 t 객체 사용. } else { // 오류 보고. } //----------- 캐스트를 사용한 버전 try { MyType t; t = (MyType)o; // MyType 타입의 t 객체 사용. } catch(InvalidCastException) { // 오류 보고 } | cs |
캐스팅을 사용한 경우에는 예외처리 코드와 null 확인 코드 모두 필요합니다.
반면, as를 사용하면 try / catch 문을 사용할 필요가 없습니다. 때문에 성능과 가독성이 좋고, null 확인 코드만 있으면 되죠!
2. 더 안전하고 런타임에 효율적으로 작동한다.
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 30 31 32 33 34 35 36 37 38 39 40 41 42 | public class SecondType { private MyType _value; // 중략 // 형변환 연산자 SecondType -> MyType public static implicit operator MyType(SecondType t) { return t._value; } } SecondType o; // obejct o = Factory.Getobject(); // o는 SecondType //----- as 연산자 사용. MyType t = o as MyType; // o가 MyType이 아니면 실패. if(t != null) { // MyType 으로 형변환된 t 사용. } else { // 실패. } //----- 캐스트 사용. try { MyType t1; t1 = (MyType) o; //MyType 형변환 된 t1 사용. } catch(InvalidCastException) { // 형변환 오류 보고. } | cs |
위에 캐스트와 as 연산자를 이용한 예제가 있습니다. 결과를 먼저 말하자면 두 버전 모두 실패합니다..!!
캐스트로 형변환 하는 경우, 사용자 정의 형변환 연산자가 호출되어 캐스팅에 성공할 것 같지만 그렇지 않습니다.
그 이유는 컴파일러는 단순히 컴파일 타임에 객체가 어떤 타입으로 선언됐는지만 추적하기 때문입니다.
컴파일러는 객체 o가 런타임에 어떤 타입인지 알 수 없어 객체 o가 object 타입이라고 생각하고 object 타입을 MyType으로 형변환 할 수 있는 연산자가 정의되어 있는지를 확인합니다.
as나 is는 런타임에 객체의 타입을 확인하지만, 필요에 따라 박싱을 수행하는 것을 제외하고는 어떠한 작업도 수행하지 않습니다. 따라서, as, is 형변환은 사용자 정의 형번은 수행되지 않습니다. as, is를 사용하여 형변환을 수행하려면 변환하고자 하는 객체는 지정한 타입이거나 지정한 타입을 상속한 타입이어야 합니다. 이 외에는 모두 실패하게 됩니다.
다시 말해, t = st as MyType; 에서 st 가 MyType 이거나 MyType을 상속한 타입이 아니라면 컴파일 오류를 발생하게 될겁니다. 이처럼 as, is 연산자가 결과의 일관성이 높고 더 안전하며 런타임에 효율적입니다.
- 사용자 정의 형변환 : https://loveme-do.tistory.com/4?category=767223
[ Digression ]
이미 C++을 공부하거나 C#을 공부하면서 C스타일의 형변환은 지양해 와서 as, is를 사용하는게 훨씬 익숙한 편인데, 캐스트가 컴파일 타임에 객체 타입을 확인해서 추적한다거나 사용자 정의 형변환은 이번에 알게 됐네요....!!
캐스트를 완전히 쓰진 않으니 써야할 경우 이에 좀 더 안전하게 대처할 수 있지 않을까 합니다.
참 고 : Effective C#