본문 바로가기
프로그래밍/C#

C# 업 캐스팅(Upcasting)에 대해서 알아보자

by bantomak 2025. 5. 19.
반응형

아래와 같은 코드를 본 적이 있는가?

List<int> list = new List<int> { 1, 2, 3 };

// IEnumerable<int>에 바로 할당 가능
IEnumerable<int> enumerable = list;
  • C#에서 List<int>를 IEnumerable<int> 바로 받을 수 있다. 이를 업 캐스팅이라고 한다.
  • 이는 완전히 정상적이며 아주 흔하게 사용되는 패턴이다.
  • 위와 같은 코드가 가능한 이유는, List<int>IEnumerable<int>를 구현하고 있기 때문이다.

업 캐스팅(Upcasting)이란?

  • 상속/구현 관계에서 자식을 부모로 형 변환하는 것
  • 명시적 형변환 없이 자연스럽게 가능 (암시적 형변환)
void PrintNumbers(IEnumerable<int> numbers)
{
    foreach (var number in numbers)
    {
        Console.WriteLine(number);
    }
}

var list = new List<int> { 1, 2, 3 };
PrintNumbers(list); // List<int>을 IEnumerable<int>로 암시적 업캐스팅

왜 가능한가?

public class List<T> : IList<T>, ICollection<T>, IEnumerable<T>, ...
  • List<T> 클래스는 다음과 같은 인터페이스를 구현한다.
  • 즉, List<int> 본질적으로 IEnumerable<int> 이기도 하다.
  • 따라서, List<int> 자동으로 IEnumerable<int> 업캐스팅이 가능하다.

IEnumerable<T>는 무엇인가?

  • IEnumereable<T>는 값을 하나씩 순차적으로 열거할 수 있는 객체를 의미한다.
  • 가장 기본적인 컬렉션 인터페이스이며, foreach, LINQ, yield return 등에 쓰인다.
  • IEnumerable<T>는 값을 읽기만 가능
  • 요소 추가 및 삭제 불가능 (List<T>, ICollection<T>에서만 가능)

IEnumerable<T>로 업캐스팅하는 목적

void PrintAll(IEnumerable<int> numbers)
{
    foreach (var num in numbers)
        Console.WriteLine(num);
}
  • 구현체에 의존하지 않고, 인터페이스로 추상화
  • 해당 함수는 List<int>, int[], HashSet<int> 등 모든 IEnumerable<int> 구현체를 받을 수 있음
  • 구체적인 타입에 의존하지 않기 때문에 확장성과 재사용성이 높아짐
IEnumerable<int> nums = list;
nums.ToList().Add(999); // 추가 가능! List<int>는 추가 가능
// nums.Add(999); // 추가 불가! IEnumerable은 추가 불가능
  • 읽기 전용 시멘틱 전달
  • IEnumerable<T>는 열거만 가능하고 변경은 못함
  • 메서드 시그니처에서 IEnumerable<T>를 사용하면 "읽기 전용으로 쓰겠다"는 의도를 전달
List<int> list = new List<int> { 1, 2, 3 };
IEnumerable<int> squared = list.Select(x => x * x); // OK
  • LINQ와 잘 어울림
  • LINQ는 IEnumerable<T>를 기반으로 설계되어 있음
IEnumerable<int> list = new List<int> { 1, 2, 3 };
IEnumerable<int> set = new HashSet<int> { 1, 2, 3 };

void Print(IEnumerator<int> e) { ... } // 구현체 구분 없이 처리 가능
  • 다형성 활용

정리하자면

  • 업 캐스팅(Upcasting) : 자식 타입을 부모 타입으로 형변환
  • 목적 : 추상화, 다형성, 유연성 확보, 읽기 전용 전달
  • 실무 적용 : 함수 매개변수, 리턴 타입, LINQ, 테스트 등에서 인터페이스 기반 프로그램에 매우 중요

댓글