반응형
아래와 같은 코드를 본 적이 있는가?
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, 테스트 등에서 인터페이스 기반 프로그램에 매우 중요
'프로그래밍 > C#' 카테고리의 다른 글
C# readonly 사용시 값 타입 vs 참조 타입 차이점 (0) | 2025.06.16 |
---|---|
C# JSON 직렬화/역직렬화 옵션을 설정하는 여러 방법 (0) | 2025.06.01 |
C# 얕은 복사, 깊은 복사에 대해서 알아보자 (0) | 2025.05.19 |
C# EF Core 사용시 DB 상태를 간단하게 체크하는 방법 (0) | 2025.05.19 |
UseForwardedHeaders를 이용해서 클라이언트 실제 IP 얻기 (0) | 2025.05.19 |
댓글