<제네릭 메서드>
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 Framework에는 다양한 제네릭 클래스들이 포함되어 있다.
특히 System.Collections.Generic 네임스페이스에 있는 모든 컬렉션 관련 클래스들은 제네릭 타입이다.
<문법 예시>
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 : struct | T는 값 형식이어야 함 (Nullable 불가) |
where T : class | T는 참조 형식이어야 함 |
where T : unmanaged | T는 비관리 형식이어야 함 (C# 7.3 이상) |
where T : enum | T는 열거형이어야 함 (C# 7.3 이상) |
where T : delegate | T는 대리자 형식이어야 함 (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("플레이어에게 공격!");
}
}
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() { }
}