티스토리 뷰


강제 형 변환보다는 as, is가 좋다!

 

C#에서도 C, C++, Java등에서 사용하던 강제 형 변환을 할 수 있다.

 

형 변환 예)

void EventHandler(object obj, EventArgs e)

 {

     MyClass myClassByCast = (MyClass)obj; // cast사용

     MyClass myClassByAs = obj as MyClass; // as 사용

 }

 

C#에서는 위처럼 object형을 형 변환해야 할 때가 종종 있다.

 

중요한 점은 위처럼 강제 cast를 하나 as키워드를 사용하나 그 결과는 같다는 것이다.

그렇다면 왜 as키워드를 사용해야 하는 걸까?

 

1. as is 연산자는 런타임에 객체의 형 변환이 가능한지를 확인하기 위해서 사용자가 정의한 형 변환 연산자를 고려하지 않는다.  è 애초에 형 변환이 불가능 한 경우(객체가 변환 요청된 타입이거나 변환 요청타입으로부터 상속된 타입이 아닌 경우)에는 컴파일 때 에러를 발생한다.

반면 cast 연산의 경우 컴파일러는 객체를 변환 요청된 타입으로 변경할 수 있는 다양한 형 변환 연산자를 고려하여 형 변환을 수행하는 코드를 만들어낸다.

 

이러한 점을 고려하여 예외를 코려한 코드로 바꾼다면 이러한 식이 될 것이다.

 

예외상황을 고려한 형 변환 예)

try

{

    MyClass myClassByCast = (MyClass)obj; // cast사용

    if (myClassByCast != null)

    {

        // 객체 사용

    }

    else

    {

        // null 경우 오류 보고

    }

}

catch

{

    // 변환 오류 보고

}

 

MyClass myClassByAs = obj as MyClass; // as 사용

if (myClassByAs != null)

{

    // 객체 사용

}

else

{

    // null 경우 오류 보고

}

 

 

눈에 띄는 점 두 가지는

1. 강제 형 변환의 경우 try catch를 사용하여 형 변환에 대한 예외를 따로 잡아야 한다는 점,

2. 어떠한 경우를 사용해도 null은 변환될 수 있기 때문에 if/else를 사용하여 잡아줘야 한다는 점

이 될 것이다.

 

위의 말을 종합하여 보았을 때 한마디로 요약하자면

강제 형 변환의 경우 형 변환이 수행될 수도 있고 그렇지 않을 수도 있지만, as 키워드를 사용하면 형 변환이 100% 수행될 것이라 판단할 수 있다.’

 

그렇다면 is키워드는 언제 사용하는 것 인가?

그것은 어쩔 수 없이 강제 형 변환을 사용할 경우가 생길 때 이다.

 

as키워드는 변환할 타입이 Reference형일 때만 사용할 수 있다. value타입은 as키워드를 사용하여 형 변환할 수 없으며, 이럴 때 강제 형 변환을 사용하게 된다. 하지만 위 내용과 같이 강제 형 변환은 형 변환 수행에 대한 보장을 하지 않기 때문에, 형 변환 가능 여부를 미리 살피기 위해 is키워드를 사용한다.

 

예를 들어 object형을 int로 변환하려 한다면 as키워드는 동작하지 않는다.(컴파일 에러)

value타입으로의 형 변환

object o = MyClass.GetValue();

 

int i = (int)o;     // 동작

int j = o as int;   // 에러

에러 메시지는 다음과 같다 :

오류 : as 연산자는 참조 형식 또는 nullable 형식과 함께 사용해야 합니다. 'int'() null을 허용하지 않는 값 형식입니다.

 이런 경우에 is연산자를 사용할 수 있다.

is 연산자를 사용함으로써 얻을 수 있는 이점은 위에서 말한 것과 같이 형 변환 수행동작을 보장할 수 있기 때문에 굳이 try / catch를 사용하지 않아도 된다는 점이다.

 

위의 예제를 is키워드를 사용하여 예외를 고려한 코드로 바꾼다면 다음과 같다.

value타입으로의 형 변환

object o = MyClass.GetValue();

 

int i;

if(o is int)

    i = (int)o;     // 동작

 

 

요약 :

1. Reference 타입의 형 변환을 할 경우 as연산자를 사용하여 형 변환을 보장하자!

2. 강제 형 변환을 사용할 경우 is키워드를 사용하여 형 변환을 보장하자!

반응형
댓글