형식을 변환하기 위해 캐스트 연산자를 사용한다.
double pi = 3.14;
int p = (int)pi; // double 타입 값 3.14를 int 타입으로 캐스팅
이런 식으로 값을 다른 형식으로 변환하거나,
enum FruitType
{
Apple,
Banana,
Grape,
Orange,
Pineapple,
Mango
}
static void Main(string[] args)
{
int i = (int)FruitType.Apple;
FruitType f = (FruitType)2;
}
이런 식으로 열거형에도 사용할 수 있고,
private void button_Click(object sender, EventArgs e)
{
MessageBox.Show(((Button)sender).Text + " Clicked.");
}
이렇게 참조 형식 형변환에도 물론 사용 가능하다.
그러나 위 방법은 참조 형식에 대해서는 썩 좋은 방법은 아니다.
가령 어떤 클래스의 인스턴스를 전혀 다른 클래스의 참조 변수로 참조하기 위해 아래와 같이 캐스팅을 수행하면 예외가 발생할 것이다.
class ClassA {}
class ClassB {}
static void Main(string[] args)
{
object a = new ClassA();
ClassB b = (ClassB)a; // InvalidCastException : ClassA 형식 개체를 ClassB 형식으로 캐스팅할 수 없습니다.
}
참조 형식에 대해서는 as 키워드를 사용해 캐스팅할 수 있다.
캐스트 연산자와 as의 다른 점은 캐스트 연산자는 위와 같이 형변환에 실패할 경우 예외를 던지지만, as 키워드는 형변환에 실패한 경우 예외를 던지지 않고 null을 대입해준다.
class ClassA {}
class ClassB {}
static void Main(string[] args)
{
object a = new ClassA();
ClassB b = a as ClassB; // 캐스팅 불가하므로 b에는 null이 대입
}
is 키워드는 캐스팅이 가능한지의 여부를 bool 값으로 돌려준다.
class ClassA {}
class ClassB {}
static void Main(string[] args)
{
object a = new ClassA();
ClassB b;
if(a is ClassB) b = a as ClassB;
else b = new ClassB();
}
주의할 점은 as 키워드는 null을 허용할 수 있는 참조 형식에 대해서만 사용이 가능하다는 점이다. 아래와 같이 값 혹은 값 형식 변수에 대해서는 사용할 수 없다. 값 형식 변수에는 혹시 캐스팅이 실패하더라도 null을 대입하는 것이 불가능하기 때문이다.
void func(object a)
{
if (a is double) var b = a as double; // 컴파일 에러.
}
위와 같이 is를 사용해 형변환이 가능한지의 여부는 확인이 가능하나, as를 사용해서 형변환 시도를 하는 것은 불가능하다.
is 키워드는 조건식 등에서 아주 강력한 성능을 낼 수 있다.
void func (object obj)
{
if (obj is TextBox box) MessageBox.Show($"TextBox:{box.Name} ({box.Text})");
else if (obj is NumericUpDown num) MessageBox.Show($"NumericUpDown:{num.Name} ({num.Value})");
}
obj is TextBox box 이 문장은 obj가 TextBox로 변환 가능한 경우 변환하여 변수 box에 대입해주며, 식의 결과값은 true가 된다. 이후 box 변수는 해당 문장이 포함된 블록 혹은 메서드가 종료될 때까지 유효하다.
'.NET > C#' 카테고리의 다른 글
[C#] using 구문 사용법 (0) | 2021.07.23 |
---|---|
[C#] delegate와 delegate 체인 (0) | 2021.07.20 |
[C#] 소켓 연결 시도에 타임아웃 넣기 (0) | 2021.07.14 |
[C#] 문자열 보간 기능 (0) | 2021.07.14 |
[C#] 확장 메서드를 사용해 메서드 호출을 간결하게 하기 (0) | 2021.07.09 |