[C#] Generic<T>의 모든 것

2024. 6. 18. 12:02·C#

중요 개념 제네릭

#0. 프롤로그

유니티에서 코드를 작성하면 "Getcomponent<T>();"와 같은 제네릭을 많이 보게 된다.

얼마 전에는 정확한 의미를 잘 모르겠다고 여쭤보시는 분이 계셔서 모든 타입을 받는 경우에 사용한다고 짧막하게 답변드린 적이 있는데 내가 생각해도 깊이감이 없는 답변이라고 생각되어, 이번 포스팅을 통해 제네릭에 대해 제대로 정리해보고자 한다.


#1. 제네릭(Generic)이란?

제네릭(Generic)은 메서드(함수)나 클래스를 작성할 때 데이터 형식(Type)을 지정하지 않는다,

그렇기에 코드로 작성한 후, 실제 사용하는 시점에서 데이터 형식을 지정할 수 있도록 하는 기능이다. 

제네릭은 재사용성이 높고 컴파일 시점에서 타입 체크를 하기 때문에 안정적이다.

덕분에 제네릭을 쓰면 코드의 가독성과 유지보수성을 향상시킬 수 있는 장점이 존재한다.

제네릭이 생긴게 <T> 이렇게 T에다가 모든 데이터 타입을 넣을 수 있다.

 

데이터 타입은 말 그대로 자료형(Data Type)이다.

아래와 같은 자료형들을 얘기한다.

  • 값 형식
    • int, float, double, bool, struct 등
  • 참조 형식
    • string, object, class 등
  • 사용자 정의 형식
    • enum, delegate, interface, struct 등

위의 형식 외에도 사용자 정의 자료형이면 인식이 된다.

이제 제네릭 메서드와 클래스를 보면서 이해해보자.


#2. 제네릭 메서드(Method)

우선 제네릭으로 함수 작성하는 방법을 보자.

T Generic<T>(T a) 로 선언하고 

public T Generic<T>(T a)
{
    return a;
}

 

사용할 때 T(Type)에 해당하는 타입에 int를 넣는다면 나머지 T도 int로 정해진다.

 

예를 들어, 위의 제네릭 함수는 return a;로 Type을 int로 반환하고 싶다면

제네릭 함수를 선언할 때 GetMax<T>의 T에다가 int를 넣으면 된다.

그러면 뒤에 따라오는 매개변수 a, b도 int로 인식이 되는걸 볼 수 있다.

var num은 말그대로 int말고 다른 타입이 와도 인식하기 위한 거니 int num이랑 똑같다.

 

실제로도 int 대신 Transform 넣으면 리턴 값도 Transform이여야하는 것을 볼 수 있다.


#3. ref 키워드

다른 곳에서 자료를 찾다보니 제네릭 메서드에 ref 키워드를 항상 쓰는 느낌이다.

ref 키워드는 메서드(함수)의 인수로 전달되는 값의 참조를 전달하기 위해 사용한다.

일반적으로 값형식인 변수의 값을 변경하거나 외부에게 객체의 참조를 전달하는 식으로 사용한다.

그래서 제네릭을 사용할 때 ref 키워드가 무조건 필요한건 아니다.

 

사용방법은 간단하다.

public T Generic<T>(ref T a)
{
    return a;
}

위의 제네릭 메서드랑 똑같이 하고 매개변수 부분에 ref 키워드 넣어주면된다.


#4. 제네릭 클래스(Generic Class)

사실 기본적으로 제네릭 하면 제네릭 클래스를 더 많이 볼 수 있다.

제네릭 클래스의 기본적인 형태는 다음과 같다.

접근제한자 class 클래스이름<T>

그리고 기본적인 선언 형태는 다음과 같다. (클래스에 특별한게 없다면)

클래스이름 <T> genericClass = new 클래스이름<T>();

근데 오른쪽에서 new 클래스이름 <T>(); 여기에 괄호()가 있다. 이건 타입 매개변수(T)다.

이는 생성자로 제네릭 클래스에 매개변수로 전달 가능하다. 예제를 보자.

public class GenericClass<T>
{
    private T data;

    public GenericClass(T data)
    {
        this.data = data;
    }

    public T GetData()
    {
        return data;
    }
}

private의 멤버 변수 하나 선언하고 생성자에서 매개변수로 입력받아 저장되게 만들었다.

이제 선언하고 우리가 원하는 자료형을 넣어서 사용해보자.

// GenericClass를 사용하여 int 형식의 데이터 저장하기
GenericClass<int> intClass = new GenericClass<int>(1);
Debug.Log(intClass.GetData()); // 1 출력

// GenericClass를 사용하여 string 형식의 데이터 저장하기
GenericClass<string> stringClass = new GenericClass<string>("hello");
Debug.Log(stringClass.GetData()); // "hello" 출력

 

보다시피 <T>에 해당하는 우리가 원하는 자료형을 넣은 뒤 괄호 사이에 데이터를 저장했다.

이런식으로 타입 매개 변수(T)의 응용이 가능하다.


#5. where 키워드, 제약조건이란?

마지막으로 where 키워드인데, 이건 타입 매개 변수(T)가 만족해야 할 조건을 명시할 수 있다.

모양은 대략적으로 아래와 같이 생겼다.


접근제한자 class 클래스이름 where T : 제약조건

public class GenericClass<T> where T : new()
{
}

제약 조건에는 new() 말고도 다양하게 올 수 있다.

 

where T : struct는 값 타입인 형식에 대한 제약 조건이다.
where T : class는 참조 타입인 형식에 대한 제약 조건이다.
where T : new()는 매개 변수가 없는 기본 생성자를 가지는 형식에 대한 제약 조건이다.
where T : ParentClass는 파생된 형식에 대한 제약 조건이다. 무조건 ParentClass를 상속해야한다.
where T : ISomeInterface는 ISomeInterface 인터페이스를 구현하는 형식에 대한 제약 조건이다.
where T : struct, ISomeInterface는 값 타입 형식 + 인터페이스 형식에 대한 제약 조건이다.

위와 같은 방식들 처럼 타입을 제한도 가능하다.


"댓글과 공감 버튼은 양질의 글을 작성하는데 큰 힘이 됩니다!"

감사합니다.

'C#' 카테고리의 다른 글

[C#] 깊은 복사(Deep Copy)와 얕은 복사(Shallow Copy)  (0) 2024.05.30
[C#] property도 override가 가능하다.  (0) 2024.05.27
[C#] as와 is 연산자  (0) 2024.04.17
'C#' 카테고리의 다른 글
  • [C#] 깊은 복사(Deep Copy)와 얕은 복사(Shallow Copy)
  • [C#] property도 override가 가능하다.
  • [C#] as와 is 연산자
Logger's
Logger's
생각을 담는 공간 이곳은 게임 개발 아카이브
  • Logger's
    Game Development Archive
    Logger's
  • 글쓰기 관리
  • 전체
    오늘
    어제
    • 분류 전체보기 (24)
      • Unity (7)
      • C# (4)
      • 디자인 패턴 (3)
      • 자료구조&알고리즘 (0)
      • Tip (5)
      • 이슈 해결 (3)
      • IDE (2)
      • C++ (0)
      • C++ STL (0)
      • DirectX (0)
      • 잡담 (0)
      • 취미 (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    Computer Graphics
    Unity
    swipe
    .editorconfig
    한글 깨짐
    utf-8
    DirectX #Texturing
    drag
    모바일 환경
    DirectX #Supersampling
    유니티
    DirectX #Refraction #Reflection
  • 최근 댓글

  • hELLO· Designed By정상우.v4.10.0
Logger's
[C#] Generic<T>의 모든 것
상단으로

티스토리툴바