[C#] 상속 관계에 있는 클래스의 형변환
is 연산자와 as 연산자
C++의 다운 캐스팅과 연관된 연산자인 듯 하다.
예전 dynamic_cast<>를 공부할 때 비슷한 내용을
다뤘던 것 같다. C#에서는 좀 더 세련된(?) 형변환을
위해 멋진 연산자 두 개를 제공한다. 바로 is와 as
class Mammal{
public void Nurse() { ... }
}
class Dog : Mammal {
public void Bark() { ... }
}
class Cat : Mammal {
public void Meow() { ... }
}
익히 알고 있듯이 포유류는 포유류 이고
개도 고양이도 모두 포유류이다.
Mamal m = new Mammla();
m.Nurse();
m = new Dog();
m.Nurse();
Dog dog = (Dog)m; // 다운 캐스팅이다.
dog.Nurse(); // 하지만 m이 가리키고 있는 것이
dog.Bark(); // Dog이기 때문에 가능하다.
m = new Cat();
m.Nurse();
Cat cat = (Cat)m; // 역시 다운 캐스팅.
cat.Nurse(); // 하지만 m이 가리키고 있는 것이
cat.Meow(); // Cat이기 때문에 가능하다.
위의 코드를 is 와 as 연산자를 사용해서 바꾸어보자.
먼저 is와 as를 간단하게 설명하자면
is
객체가 해당 형식에 해당하는지 검사하여
그 결과를 bool 값으로 반환한다.
as
형식 변환 연산자와 같은 역할을 한다.
다만 형변환 연산자가 변환에 실패하는 경우에
예외를 던지는 반면, as 연산자는 객체 참조를
null로 만들어 버린다. (dynamic_cast와 같은 성질)
Mammal m = new Dog();
Dog dog;
if( m is Dog ){ // 말그대로 m 이 Dog를 가리키고 있니?
dog = (Dog)m;
dog.Bark();
}
Mammal m2 = new Cat();
Cat cat = m2 as Cat; // m2를 Cat으로 형변환하라.
if( cat != null ){ // 다운 캐스팅을 하라는 말인데
cat.Meow(); // 이 경우 m2는 Cat를 가리키고 있기 때문에 가능하다.
} // 만약 m2 = new Mammal() 이었다면 불가능.
// 파생 클래스는 기본 클래스보다 더 많은 정보를 담고 있는데
// 기본 클래스에 없는 부분을 호출하려 한다면 문제가 발생.
// 때문에 이 경우 cat는 null이 된다.
C++의 시점에서 설명이 된 듯한데
확실히 C++의 dynamic_cast<> 보다는
훨씬 사용법이 간편한 것 같다.
일반적으로 형식 변환 연산자 대신 as 연산자를
사용하는 쪽이 더 권장 되는데, 형식 변환에 실패하더라도
예외가 일어나 갑자기 코드의 실행이 갑자기 점프하는 일이
없으므로 코드 관리가 더 수월해지기 때문이란다.
주의해야할 점은 as 연산자는 참조 형식에 대해서만
사용이 가능하므로 값 형식의 객체는 기존의 형식
변환 연산자를 사용해야 한다.
'C#, 유니티' 카테고리의 다른 글
[C#] 델리게이트 (delegate) (0) | 2017.03.05 |
---|---|
[C#] 인덱서 (Indexer) (0) | 2017.03.02 |
[유니티 포트폴리오] Wingz Defense , Red Sniper (0) | 2017.02.20 |
[C#] C#의 깊은 복사에 관하여 (1) | 2017.02.19 |
[C#] 가변길이 매개 변수 , 명명된 매개 변수 (0) | 2017.02.17 |