캐스팅과 형 변환은 표현식을 한 데이터 타입에서 다른 데이터 타입으로 바꾸는 서로 다른 방법이에요.
표현식은 캐스트 연산자 (<type>)를 사용해 다른 타입으로 캐스팅할 수 있어요.
long l = 1000L;
int i = (int)l;
object o = new Random();
Random r = (Random)o;
타입이 호환되지 않으면 InvalidCastException 인스턴스가 발생해요. 숫자의 경우에는 값을 받는 타입이 캐스팅된 값을 표현할 수 없다는 뜻이에요. 클래스의 경우에는 두 타입 중 하나가 다른 하나에서 파생되어야 해요(구조체에도 마찬가지로 적용돼요).
_캐스팅_의 대안은 is 연산자를 사용하는 _형 변환_이에요. 보통 참조 타입과 nullable 타입에 적용해요.
object o = new Random();
if (o is Random rand)
{
int ii = rand.Next();
// now, do something random
}
객체의 정확한 타입을 알아내야 한다면 is 연산자는 조금 너무 관대할 수 있어요. 클래스뿐만 아니라 그 클래스가 직접 또는 간접적으로 파생된 모든 클래스와 인터페이스에 대해서도 true를 반환하기 때문이에요. 이럴 때는 typeof와 Object.GetType()이 해답이에요.
object o = new List<int>();
o is ICollection<int> // true
o.GetType() == typeof(ICollection<int>) // false
o is List<int> // true
o.GetType() == typeof(List<int>) // true
우리 축구 클럽 football-match-reports 팀은 리그에서 승승장구하고 있어요. 이번에는 보안 패스 인쇄 시스템 작업을 맡아 달라는 초대를 받았어요.
지원 인력의 클래스 계층 구조는 다음과 같아요.
TeamSupport (interface)
├ Chairman
├ Manager
└ Staff (abstract)
├ Physio
├ OffensiveCoach
├ GoalKeepingCoach
└ Security
├ SecurityJunior
├ SecurityIntern
└ PoliceLiaison
이 계층 구조의 완전한 구현이 연습 문제의 소스 코드에 포함되어 있어요.
보안 패스 생성기에 전달되는 모든 데이터는 이미 검증되었고, 절대 null이 아님이 보장돼요.
SecurityPassMaker.GetDisplayName() 메서드를 구현해 주세요. 이 메서드는 Staff에서 파생된 모든 클래스의 인스턴스에 대해서는 Title 필드의 값을 반환하고, 그 외의 경우에는 "Too Important for a Security Pass"를 반환해야 해요.
var spm = new SecurityPassMaker();
spm.GetDisplayName(new Manager());
// => "Too Important for a Security Pass"
spm.GetDisplayName(new Physio());
// => "The Physio"
SecurityPassMaker.GetDisplayName() 메서드를 수정해 주세요. 1번 작업과 똑같이 동작하되, 해당 직원이 보안 팀 구성원(Security 형식이거나 그 파생 형식 중 하나)이라면 제목 뒤에 " Priority Personnel"이라는 텍스트가 표시되어야 해요.
var spm = new SecurityPassMaker();
spm.GetDisplayName(new Physio());
// => "The Physio"
var spm2 = new SecurityPassMaker();
spm2.GetDisplayName(new Security());
// => "Security Team Member Priority Personnel"
spm2.GetDisplayName(new SecurityJunior());
// => "Security Junior Priority Personnel"
SecurityPassMaker.GetDisplayName() 메서드를 수정해 주세요. 2번 작업과 똑같이 동작하되, SecurityJunior, SecurityIntern, PoliceLiaison 형식의 인스턴스에는 " Priority Personnel" 텍스트가 표시되지 않아야 해요.
var spm2 = new SecurityPassMaker();
spm2.GetDisplayName(new Security());
// => "Security Team Member Priority Personnel"
spm2.GetDisplayName(new SecurityJunior());
// => "Security Junior"
Exercism에 가입하고 C# 트랙을 개념 62개연습 문제 178개, 그리고 실제 사람의 멘토링과 함께 배우고 익혀 보세요. 모두 무료예요.