C# 제네릭(Generic) 개념 정리

식혜드식혜·2025년 4월 16일

C# 문법 정리

목록 보기
1/8

제네릭(Generic)이란?

  • C#에서 코드의 재사용성과 유연성을 향상해주는 도구이다.
  • 데이터 형식을 일반화하여 재사용 가능한 코드를 작성할 수 있게 해준다.
  • 제네릭을 사용하면 다양한 형식의 데이터를 처리하는 메서드와 클래스를 작성할 수 있으며, 컴파일 시점에서 형식 안정성(type safety)를 보장해준다.

제네릭은 언제 사용될까?

  1. 여러 데이터 형식에 대해 동일한 로직을 적용해야 할 때
  2. 컬렉션 타입에서 다양한 데이터 형식을 저장하고 관리해야 할 때
  3. 데이터 형식에 따라 다른 연산을 수행해야 할 때

제네릭 사용법

<제네릭 메서드>

public class Utility
{
    public static void Swap<T>(ref T a, ref T b)
    {
        T temp = a;
        a = b;
        b = temp;
    }
}

// 사용 예시
int a = 10, b = 20;
Utility.Swap(ref a, ref b);

<제네릭 클래스>

public class Box<T>
{
    private T value;

    public void SetValue(T val) => value = val;
    public T GetValue() => value;
}

// 사용 예시
Box<int> intBox = new Box<int>();
intBox.SetValue(123);
int result = intBox.GetValue();

.NET의 제네릭 클래스들

.NET Framework에는 다양한 제네릭 클래스들이 포함되어 있다.
특히 System.Collections.Generic 네임스페이스에 있는 모든 컬렉션 관련 클래스들은 제네릭 타입이다.

  • 예시: List, Dictionary<TKey, TValue>, Queue, Stack, LinkedList

제네릭 제약 조건(Generic Constraints)

  • 제네릭의 제약 조건은 제네릭 타입 매개변수 T에 적용되는 제한사항이다.
  • 이를 통해 특정 클래스나 인터페이스를 상속/구현하도록 강제하거나, 값 형식만 허용, 기본 생성자 요구 등의 제약을 설정할 수 있다.

<문법 예시>

public class MyClass<T> where T : 제약조건
{
    // 클래스 내용
}

public void MyMethod<T>(T param) where T : 제약조건
{
    // 메서드 내용
}

제약 조건 종류

💡 제약 조건🧾 설명
where T : 클래스명T는 해당 클래스 또는 그 파생 클래스여야 함
where T : 인터페이스명T는 해당 인터페이스를 구현한 형식이어야 함
where T : new()T는 매개변수가 없는 기본 생성자를 반드시 가져야 함
→ 다른 생성자가 있어도 상관없음
where T : structT는 값 형식이어야 함 (Nullable 불가)
where T : classT는 참조 형식이어야 함
where T : unmanagedT는 비관리 형식이어야 함 (C# 7.3 이상)
where T : enumT는 열거형이어야 함 (C# 7.3 이상)
where T : delegateT는 대리자 형식이어야 함 (C# 7.3 이상)

🔎 비관리 형식(unmanaged)이란?
값 형식이며 내부 필드들까지 모두 값 형식으로 구성된 타입으로, 메모리 레이아웃이 고정되어 있고, 포인터 연산이 안전하게 가능한 타입.

제네릭 인터페이스

  • 제네릭 인터페이스는 다양한 형식의 클래스들이 동일한 동작을 수행할 수 있도록 하는 형식 안정적인 인터페이스를 정의할 수 있다.
    <예제(유니티 게임 공격 시스템)>
public interface IAttackable<T>
{
    void Attack(T target);
}

public class Enemy : MonoBehaviour, IAttackable<Player>
{
    public void Attack(Player target)
    {
        Debug.Log("플레이어에게 공격!");
    }
}
  • 이런 제네릭 인터페이스는 Player, Enemy, Boss 등 다양한 대상에게 공격할 수 있는 구조를 유연하게 구성할 수 있게 해준다.

제네릭 싱글톤 패턴

  • MonoBehaviour 기반 클래스에 싱글톤을 적용하려면 제네릭을 이용하면 재사용성이 높아진다.
public class Singleton<T> : MonoBehaviour where T : MonoBehaviour
{
    private static T instance;

    public static T Instance
    {
        get
        {
            if (instance == null)
            {
                GameObject obj = GameObject.Find(typeof(T).Name);
                if (obj == null)
                {
                    obj = new GameObject(typeof(T).Name);
                    instance = obj.AddComponent<T>();
                }
                else
                {
                    instance = obj.GetComponent<T>();
                }
            }
            return instance;
        }
    }

    public void Awake()
    {
        DontDestroyOnLoad(gameObject);
    }
}

// 사용 예시
public class GameManager : Singleton<GameManager>
{
    public void InitGame() { }
}

✨ 마무리 팁

  • 제네릭은 코드 중복을 줄이고 타입 안정성을 높이는 데 매우 강력한 도구이다.
  • Unity나 .NET 기반 프로젝트에서도 많이 사용되며, 특히 컬렉션, 싱글톤, 인터페이스 구조에서 자주 활용된다.
profile
안녕하세요! 유니티 공부 중인 고3 학생입니다

0개의 댓글