TypenamePair
(Type, Name) 한 쌍으로 무언가를 식별하기 위한 키야.
예를 들어 같은 타입이라도 "BGM_Title" / "BGM_Battle"처럼 이름으로 변종을 구분할 수 있어.
무엇을 해결하나?
게임에선 “타입만으로는 모자라서 이름까지 필요”할 때가 많아:
•
오브젝트 풀: Bullet 타입이지만 "Pistol", "Shotgun" 풀을 따로 운용
•
리소스/사운드: AudioClip 타입이지만 "BGM_Title", "SFX_Click"
•
서비스/매니저: ISaveService 타입이지만 "Local", "Cloud" 두 구현 동시 등록
이럴 때 (Type, Name) 조합은 딕셔너리 키로 쓰기 딱 좋아.
코드가 하는 일 (핵심만)
•
struct TypeNamePair : IEquatable<TypeNamePair>
값 타입이고, 서로 같은지 비교 가능하게 만들어짐.
•
필드
◦
mType: Type (절대 null이면 안 됨)
◦
mName: string (null 넣어도 생성자에서 빈 문자열로 바꿔줌)
•
생성자
◦
TypeNamePair(Type type) → 이름은 ""
◦
TypeNamePair(Type type, string name) → type null이면 예외
•
속성
◦
Type, Name 그대로 꺼내쓰기
•
ToString()
◦
"Full.Type.Name" 또는 "Full.Type.Name.이름" 형태로 반환
◦
단, mType이 null이면 예외 (디폴트 생성된 struct 남용 방지)
•
동등성/해시
◦
Equals, GetHashCode, ==, != 구현 → 딕셔너리 키/HashSet에 안전
어떻게 써?
1) 캐시/레지스트리의 키로
// (타입, 이름) → 인스턴스 캐시
readonly Dictionary<TypeNamePair, object> _cache = new();
var key1 = new TypeNamePair(typeof(AudioClip), "BGM_Title");
var key2 = new TypeNamePair(typeof(AudioClip), "BGM_Battle");
_cache[key1] = titleClip;
_cache[key2] = battleClip;
// 어디선가 꺼낼 때
var clip = (AudioClip)_cache[new TypeNamePair(typeof(AudioClip), "BGM_Title")];
C#
복사
2) 오브젝트 풀 구분
var pistolKey = new TypeNamePair(typeof(Bullet), "Pistol");
var shotgunKey = new TypeNamePair(typeof(Bullet), "Shotgun");
// 풀 딕셔너리
Dictionary<TypeNamePair, ObjectPool> pools = new();
pools[pistolKey] = new ObjectPool(/* ... */);
pools[shotgunKey] = new ObjectPool(/* ... */);
// 스폰 시
pools[new TypeNamePair(typeof(Bullet), kind)].Spawn();
C#
복사
3) DI/서비스 컨테이너에서 구현 선택
var keyCloud = new TypeNamePair(typeof(ISaveService), "Cloud");
var keyLocal = new TypeNamePair(typeof(ISaveService), "Local");
container.Register(keyCloud, new CloudSaveService());
container.Register(keyLocal, new LocalSaveService());
// 옵션에 따라 취득
var svc = container.Resolve(new TypeNamePair(typeof(ISaveService), mode));
C#
복사
주의할 점
•
디폴트 값(struct 기본값): new TypeNamePair()처럼 생성자 없이 만들면 Type이 null이라 ToString()에서 예외가 나.
→ 항상 new TypeNamePair(typeof(...), "이름")처럼 생성자를 통해 만들자.
•
이름 규칙: 대소문자 구분을 그대로 사용하니 팀 컨벤션을 맞추자(예: 파스칼/스네이크 통일).
•
성능 메모: 값 타입(구조체)라 키로 자주 복사돼도 오버헤드가 작아. 해시는 Type과 Name을 XOR해서 빠르게 계산.
어디에 쓰이면 좋은가? (게임 맥락)
•
리소스/사운드/프리팹 레지스트리 키
•
오브젝트 풀의 변종 관리
•
상태/프로시저/FSM에서 타입별·이름별 상태 키
•
서버/클라우드/로컬처럼 구현이 여러 개인 서비스 레지스트리
요약하면, “같은 타입의 여러 버전을 동시에 다뤄야 할 때”
TypeNamePair는 딕셔너리/캐시에 넣기 좋은 안전한 복합 키라고 보면 돼.