본문 바로가기
TIL

[TIL] C# 제네릭(Generic) 이란?

by DearGreen 2024. 9. 20.

C# 제네릭(Generic) 이란?


 

C# 관련하여 공부를 다시 시작해보니, 제네릭(Generic)에 대해 알 필요성이 있다 생각해 마이크로소프트 사의 C# 공식문서를 참고해 관련 용어를 정리해보았다.

 

[제네릭(Generic) 이란?]

제네릭은 .NET에 형식 매개 변수의 개념을 소개합니다. 제네릭을 사용하면 코드에서 클래스 또는 메서드를 사용할 때까지 하나 이상의 형식 매개 변수 사양을 연기하는 클래스와 메서드를 디자인할 수 있습니다.

예를 들어 제네릭 형식 매개 변수 
T를 사용하여 여기에 표시된 것처럼, 다른 클라이언트 코드에서 런타임 캐스팅 또는 boxing 작업에 대한 비용이나 위험을 발생하지 않고 사용할 수 있는 단일 클래스를 작성할 수 있습니다.

출처 : 마이크로소프트 C# 공식 문서 - https://learn.microsoft.com/ko-kr/dotnet/csharp/fundamentals/types/generics

 

[형식 매개 변수]

: 제네릭을 통해 특정 데이터 타입을 지정하지 않고, 나중에 사용할 때 실제 타입을 지정할 수 있도록 하는 변수이다. 이를 통해 코드의 재사용성을 높일 수 있다.

 

[형식 매개 변수 - 예시]

: List<T>라는 제네릭 클래스를 예로 들어보자. 여기서 T는 형식 매개 변수이다. 다양한 타입의 리스트를 만들 수 있다.

List<int> intList = new List<int>(); // 정수 리스트
intList.Add(1);
intList.Add(2);

List<string> stringList = new List<string>(); // 문자열 리스트
stringList.Add("Hello");
stringList.Add("World");

 


 

[런타임 캐스팅]

: 런타임 캐스팅(Runtime Casting)은 프로그램 실행 중에 객체의 타입을 변환하는 과정이다. C#에서는 주로 참조 타입 간의 변환을 다룰 때 사용한다. 이 과정은 두 가지 형태(명시적 캐스팅암시적 캐스팅) 로 진행된다.

 

[런타임 캐스팅 - 명시적 캐스팅]

: 개발자가 명시적으로 타입을 변환할 때 사용한다. 이 경우, 변환이 안전한지 확인해야 하며, 변환이 실패할 경우 예외가 발생할 수 있다.

object obj = "Hello, World!";
string str = (string)obj; // 명시적 캐스팅

 

 

 위의 예에서 objobject 타입이고, 이를 string으로 변환한다. 만약 obj가 실제로 string이 아닐 경우, InvalidCastException이 발생한다.

 

[런타임 캐스팅 - 암시적 캐스팅]

: 타입 간의 변환이 안전하다고 컴파일러가 판단할 때 자동으로 이루어진다. 주로 상위 클래스에서 하위 클래스로의 변환이 해당된다.

int number = 42;
object obj = number; // 암시적 캐스팅 (박싱)

 

 

위의 예에서 int는 값 타입이고, object는 참조 타입이다. intobject로 변환할 때는 박싱이 발생하며, 이는 자동으로 처리된다.

 


 

[박싱(Boxing) & 언박싱(Unboxing)]

: C#에서 값 타입과 참조 타입 간의 변환을 설명하는 개념이다. 이 두 과정은 메모리 관리와 성능에 중요한 영향을 미친다.

 

[박싱 (Boxing)]

  • 정의: 값 타입(예: int, double, struct)을 참조 타입(예: object)으로 변환하는 과정이다.
  • 작동 방식: 값 타입의 인스턴스가 힙(heap) 메모리에 저장되고, 해당 인스턴스에 대한 참조가 생성된다. 이 과정을 통해 값 타입이 "상자(box)"에 담기는 것처럼 보인다.
int number = 42;
object obj = number; // 박싱

위의 코드에서 number는 값 타입인 int이고, 이를 object 타입으로 변환하면서 힙에 박싱된다.

 

[언박싱 (Unboxing)]

  • 정의: 박싱된 참조 타입을 다시 원래의 값 타입으로 변환하는 과정이다.
  • 작동 방식: 힙에 저장된 값 타입의 인스턴스를 참조하여 원래의 값 타입으로 복원된다. 이 과정은 명시적으로 이루어져야 하며, 타입이 일치해야 한다.
object obj = 42; // 박싱된 상태
int number = (int)obj; // 언박싱

여기서 obj는 object 타입이지만, 실제로는 int를 저장하고 있다. 언박싱을 통해 다시 int로 변환한다.

  • 박싱과 언박싱은 추가적인 메모리 할당과 CPU 사이클을 요구하므로 성능 저하를 초래할 수 있다. 특히, 반복문이나 대량의 데이터 처리 시 이러한 성능 저하가 눈에 띄게 나타날 수 있다.
  • 따라서, 제네릭을 사용하면 박싱과 언박싱을 피할 수 있어 성능이 향상된다. 예를 들어, List<int>는 int를 직접 저장하므로 박싱이 필요 없다.

공식 문서의 용어를 해설하는데도 C#에 대한 배경지식과 이해가 필요했다. 앞으로 더 배워보자.

'TIL' 카테고리의 다른 글

[TIL] C# 경고 잡기 : CS8618 이란?  (0) 2024.09.24
[TIL] C# Class란?  (1) 2024.09.23
[TIL] 유니티 싱글톤 패턴 활용  (1) 2024.09.13
[TIL] 디자인 패턴이란  (1) 2024.09.11
[TIL] Git Commit Message 작성  (1) 2024.09.10