[03] 캐스트보다는 is, as가 좋다

다음 본문은 도서 이펙티브 C# (빌 와그너)에서 나오는 주제를 다룹니다.

 

as를 사용한 객체 사용

 - as는 형 변환을 수행할 수 없거나, null을 대상으로 형 변환을 수행하는 경우 null을 반환한다.

 - null처리만 해주면 된다.

object o = Factory.GetObject();

MyType t = o as MyType;

if(t != null)
{
    // 객체 사용
}
else
{
    // 오류 보고
}

 

캐스트 연산자를 사용한 객체 사용

 - 형변환을 수행할 수 없다면 오류가 발생한다.

 - null은 어떠한 참조값으로도 변환될 수 있기 때문에 null 처리도 별도로 수행해야 한다.

object o = Factory.GetObject();

try
{
    MyType t;
    t = (MyType)o;
    // MyType 타입의 t 객체 사용
}
catch(InvalidCastException e)
{
    // 오류 보고
}

 

차이점 : 사용자 정의 형 변환 연산자

 - as는 해당 객체가 지정 타입이거나, 지정 타입을 상속한 타입일 경우만 박싱을 수행한다.

 - 캐스트는 객체를 지정한 타입으로 변환하기 위해서 형 변환 연산자가 개입될 수 있다.

   (하지만 컴파일 타임 타입에 대한 형 변환만 인식한다.)

 

 - 때문에 as캐스트보다 일관성 있는 결과를 가진다.

 

as를 사용할 수 없는 경우 : 숫자 변환

 - 만약 o가 정수가 아니라면 null을 사용할 수 없음으로 컴파일되지 않는다.

object o = Factory.GetValue();
int i = o as int; // 컴파일 되지 않음

 - 따라서 nullable 타입을 사용하면 된다.

object o = Factory.GetValue();
int? i = o as int?; // 컴파일 되지 않음
if(i != null)
    Console.WriteLine(i.value);

 

foreach 루프

 - foreach는 제네릭 타입이 아닌 IEnumerable 인터페이스를 사용한다.

 - 이 과정에서 형 변환을 수행한다.

 

is 연산자

 - 상속한 하위 타입일 경우에도 true를 반환한다.

 - 때문에 엄격하게 테스트를 수행해야 할 경우에는 GetType() 메서드로 런타임 객체 타입을 비교하자.

 

결론

 - 캐스팅보다는 is와 as 연산자를 사용한다면 의도하지 않은 사이드 이펙트를 피할 수 있다. 

 

 

댓글

Designed by JB FACTORY