형변환

황현중·2025년 12월 2일

C#

목록 보기
19/24

1. 형변환이란?

형변환(캐스팅) = 어떤 타입의 값을 다른 타입처럼 취급하는 것

예를 들면:

int i = 10;
double d = i;      // int → double

이렇게 int 값을 double 변수에 넣는 것도 형변환이다.
C#에서는 크게 이런 종류들이 자주 나온다.

  • 묵시적 형변환 (implicit)
  • 명시적 형변환 (explicit, (타입) 캐스팅)
  • 참조 타입 캐스팅 (상속 관계, is, as)
  • 박싱/언박싱 (값 타입 ↔ object)

2. 묵시적 형변환 (Implicit Conversion)

컴파일러가 “이건 안전하다”라고 보고, 자동으로 해주는 형변환이다.
주로 “작은 타입 → 큰 타입”으로 갈 때 가능하다.

2-1. 숫자끼리 묵시적 형변환

int i = 10;
double d = i;   // OK, int → double 자동 변환
  • int는 4바이트, double은 8바이트
  • int 값은 모두 double로 표현 가능
  • 데이터 손실 위험이 거의 없기 때문에 C#이 자동으로 허용

다른 예:

byte b = 100;
int i = b;      // OK, byte → int
long l = i;     // OK, int → long
float f = l;    // OK, long → float (근사값이 될 수 있지만 허용)

한 줄로 정리하면:

“작은 그릇 → 큰 그릇”으로 가는 건 대부분 자동 형변환이 된다.

3. 명시적 형변환 (Explicit Casting)

이번에는 반대로, 개발자가 직접 (타입)을 써줘야 하는 경우다.
주로 “큰 타입 → 작은 타입” 또는 데이터 손실 가능성이 있는 경우에 필요하다.

3-1. 숫자끼리 명시적 형변환 예제

double d = 3.14;
int i = (int)d;   // i는 3 (소수점 잘림)
  • 소수점 이하 정보가 날아갈 수 있기 때문에
  • C#은 자동 변환을 허용하지 않는다.
  • 개발자가 (int)를 써서 “내가 책임진다”고 표시해야 한다.

또 다른 예:

int big = 300;
byte b = (byte)big;  // 값이 잘릴 수 있음 (0~255 범위를 넘어서면 값이 뒤틀림)

이런 식으로 데이터가 잘리거나 값이 달라질 수 있는 변환은 반드시 (타입)으로 명시적 캐스팅이 필요하다.


4. 참조 타입 형변환 (상속, 업캐스팅/다운캐스팅)

숫자 타입만 형변환이 있는 게 아니다. 클래스/인터페이스 같은 참조 타입도 형변환이 있다.

4-1. 업캐스팅(Upcasting): 자식 → 부모 (안전, 묵시적)

class Animal
{
    public void Eat() => Console.WriteLine("먹는다");
}

class Dog : Animal
{
    public void Bark() => Console.WriteLine("멍멍");
}

class Program
{
    static void Main()
    {
        Dog d = new Dog();
        Animal a = d;   // 업캐스팅: Dog → Animal (묵시적 형변환 가능)

        a.Eat();        // OK
        // a.Bark();    // 컴파일 에러 (Animal 타입에는 Bark가 없음)
    }
}
  • DogAnimal을 상속하므로, Dog는 곧 Animal이다.
  • 자식 → 부모로 가는 건 항상 안전하다.
  • 그래서 C#이 자동으로 형변환을 허용한다(묵시적).

4-2. 다운캐스팅(Downcasting): 부모 → 자식 (명시적, 위험할 수 있음)

Animal a = new Dog();   // 실제 인스턴스는 Dog
Dog d = (Dog)a;         // 다운캐스팅 (OK)

d.Bark();               // 사용 가능

하지만 이런 경우도 있다:

Animal a = new Animal();
Dog d = (Dog)a;   // 컴파일은 되지만, 실행 시 InvalidCastException 발생
  • a의 실제 인스턴스는 Animal일 뿐, Dog가 아니다.
  • 이 경우 다운캐스팅하면 런타임에서 예외가 터진다.

그래서 C#에서는 안전하게 형 변환을 하기 위해 isas를 제공한다.


5. is, as 연산자

5-1. is : “이 타입이 맞냐?” 검사

Animal a = new Dog();

if (a is Dog)
{
    Console.WriteLine("a는 Dog 타입이다");
}

C# 패턴 매칭을 쓰면 이렇게도 가능하다.

if (a is Dog d)
{
    d.Bark(); // 여기서 d는 Dog 타입으로 캐스팅된 상태
}

5-2. as : 캐스팅 시도, 안 되면 null

Animal a = new Dog();

Dog d = a as Dog;   // 캐스팅 성공 → d는 Dog
if (d != null)
{
    d.Bark();
}

Animal a2 = new Animal();
Dog d2 = a2 as Dog; // 캐스팅 실패 → d2는 null
  • as는 예외를 던지지 않는다.
  • 캐스팅이 안 되면 그냥 null을 돌려준다.
  • 그래서 보통 if (d != null) 체크와 같이 사용한다.

6. 문자열 ↔ 숫자 변환 (Parse / TryParse)

이건 엄밀히 말하면 “캐스팅”보다는 파싱(Parsing)이지만, 실무에서는 형변환과 같이 다루는 경우가 많다.

string s = "123";

// 문자열 → 숫자
int i1 = int.Parse(s);             // 실패 시 예외 발생

int i2;
bool ok = int.TryParse(s, out i2); // 실패해도 예외 없이 false 반환

// 숫자 → 문자열
int n = 456;
string s2 = n.ToString();
  • 문자열 → 숫자: Parse, TryParse
  • 숫자 → 문자열: ToString()

7. 박싱(Boxing) / 언박싱(Unboxing)

C#에서는 모든 타입이 궁극적으로 object를 상속한다.
그래서 int 같은 값 타입도 object로 다룰 수 있는데, 이때 등장하는 개념이 박싱/언박싱이다.

7-1. 박싱(Boxing) – 값 타입 → object

int i = 10;
object o = i;   // 박싱 발생

값 타입 i가 힙에 object 형태로 포장되는 느낌으로 이해하면 편하다.

7-2. 언박싱(Unboxing) – object → 값 타입

object o = 10;     // int 박싱
int i = (int)o;    // 언박싱 (명시적 캐스팅 필요)

주의할 점:

object o = 10;   // 실제로는 int

double d = (double)o;  // 런타임 오류 (InvalidCastException)
  • o 안에 실제 들어있는 건 int인데,
  • double로 바로 캐스팅하려고 하면 예외가 발생한다.
  • 언박싱은 “원래 값 타입”으로만 가능하다.

8. 한 번에 정리

  • 묵시적 형변환 (implicit)
    • 컴파일러가 자동으로 해주는 형변환
    • 주로 작은 숫자 타입 → 큰 숫자 타입, 자식 → 부모(업캐스팅)
    • 예: int i = 10; double d = i;
  • 명시적 형변환 (explicit casting)
    • (타입)을 써서 개발자가 직접 캐스팅
    • 데이터 손실 가능성이 있을 때 필요
    • 예: double d = 3.14; int i = (int)d;
  • 참조 타입 캐스팅
    • 상속 관계에서의 형변환
    • 업캐스팅: 자식 → 부모 (자동, 안전)
    • 다운캐스팅: 부모 → 자식 (명시적, 잘못하면 런타임 예외)
    • is, as로 안전하게 검사/캐스팅 가능
  • 문자열 ↔ 숫자 변환
    • 문자열 → 숫자: int.Parse, int.TryParse
    • 숫자 → 문자열: ToString()
  • 박싱 / 언박싱
    • 값 타입 → object로 포장: 박싱
    • object → 값 타입으로 꺼내기: 언박싱 ((int)o 같은 형변환 필요)
    • 언박싱은 원래 타입으로만 가능

0개의 댓글