generic 타입 소개와 object, var 대신 사용하는 이유

만약에 나만의 리스트를 만들고 싶을 때, 리스트의 타입마다 하나씩 만들 수도 있을 것이다.

그렇다면 이 때, 각 타입의 리스트를 선언하기 위해 매번 다시 새롭게 선언해야 할까?

 

 

 

 

이를 위해 우선 생각해볼 수 있는 문법이 object이다.

object 타입은 어떤 타입을 받아도 소화할 수 있다.

하지만 반환할 때 캐스팅을 해야 한다.

object obj = 3;
object obj2 = "hello";
int num = (int)obj;
string str = (str)obj2;

 

 

 

var 라는 것도 비슷하지만 조금 다르다.

var는 타입을 명시적으로 입력하지 않아도 할당받은 값을 보고 컴파일러가 적당히 때려맞춘다는 느낌이다.

그래서 우리가 코드편집기에 값을 입력하자마자 바로 해당 타입이 된다. (그래서 여러개 받기는 무리)

 

 

 

 

반대로 object는 정말 object라는 타입이 된 것이다.

그렇다면 오히려 이것은 어떻게 다 받을 수 있는건가 싶다.

컴파일러가 맞춰주는 것도 아닌데 어떻게 가능한것일까

 

 

 

C#은 전부 최상위 클래스에 있는 object라는 클래스를 상속받고 있다.

int나 string 타입도 object 클래스 안에 있는 것을 상속받아서 사용하고 있던 것이다. (그래서 다 받을 수 있던것)

 

그런데 object에서 값을 넣고 출력하는 것은 속도가 느리다.

 

int같은 것은 heap이 아니라 stack에 들어가는 정보였다.

즉, 간편한 복사타입의 변수였는데, 오브젝트는 참조타입이다.

 

예를들어 힙에다 메모리를 할당해서 3이라는 숫자를 넣고 빼온 것이다.

 

 

 

그래서 var나 object 같은 타입보다 일반화해서 사용할 수 있는 generic이란 문법이 있다.

 

class MyList<T>
{
	T[] arr = new T[10];
    
    T GetItem(){}
}

class Monster
{
}

static void main()
{
	
    MyList<int> myIntList = new MyList<int>();
    MyList<string> myIntList = new MyList<string>();
    MyList<Monster> myIntList = new MyList<Monster>();
}

 

사용하는 방법은 간단하다. 

클래스 옆에 꺾쇠 하고 일반화 시킬것의 이름을 적는데, 보통 템플릿의 약자인 T를 쓴다.

 

 

위에서 구현한 generic 클래스 안의 내용은

T라는 타입 안에서 어떤 T라는 타입을 넣어도 잘 동작한다는 의미이다.

 

 

 

 

여기서 조금 더 나아가서, generic 타입에 조건을 추가할수있다.

 

class MyList<T> where T : struct

 

 

where 뒤에 오는 T : strutc가 갖는 의미는

어떤 T든 상관없지만 T는 반드시 값 형식이어야 한다고 명시하는 것이다.

 

값이 아니라 참조형식이어야 한다면 T : class로 쓴다.

 

 

 

추가로

T : new()는 반드시 어떠한 인자도 받지 않는 생성자가 있어야 한다는 조건

 

 

아니면 위에서 선언한 Monster 클래스를 사용하여

T : Monster 를 쓰면, 이 클래스 혹은 이 클래스를 상속받은 클래스가 와야 한다는 조건이다.

'언어 > C#' 카테고리의 다른 글

property 소개  (0) 2024.07.08
추상 클래스와 인터페이스  (0) 2024.07.08
배열과 리스트, 딕셔너리  (2) 2024.07.04
객체지향의 원칙 상속성, 은닉성, 다형성  (0) 2024.07.03
C# 기본 지식  (0) 2024.07.02