C# / Unity에서 일반화란
특수한 개념으로부터 공통되는 개념을 찾아 묶어 일반화 시키는 것이다.
일반화 하는 대상은 데이터 형식(type)이다.
일반화를 할 때 object 형식을 쓰는 것이 편리하다.
object 데이터 형식을 이용하면 여러 데이터를 한 변수에 저장 가능하기 때문.
위와 같이 int형 배열에는 string타입을 넣을 수 없다.
하지만 위에서 설명한 object 형식으로 배열 타입을 지정해준다면 다양한 타입을 다 넣을 수 있다.
이때 내부적으로 박싱 / 언박싱이 일어나게 된다.
하지만 object 형식은 박싱 / 언박싱을 할 때의 속도 저하로 인해 쓰이지 않는다.
또한 데이터 형식을 명확하게 알 수 없다는 단점도 있다.
int num1 = 1;
object obj = num1; //박싱
int num2 = (int)obj; //언박싱
제네릭 (Generic)
object 대신 쓰이는 것이 제네릭(Generic) 이다.
제네릭은 일반화 대상을 정의 할 때에 <>안에 일반화할 대상에 대해 작성 후 사용하기 때문에
데이터 형식을 보다 명확하게 알 수 있고, 박싱 / 언박싱에 소모되는 속도 저하도 받지 않는다.
private void TestMethod<T>(T obj) //제네릭 메소드
{
}
private class TestClass<T> //제네릭 클래스
{
}
제네릭 메소드
사용방식 ↴ (형식매개변수는 T이다.)
한정자 반환형식 메소드이름<형식매개변수>(매개변수목록)
{
//실행 코드
}
메소드 이름 뒤 < 와 > 사이에 T를 넣고, 메소드 호출 시 T 대신 사용할 데이터 형식을 입력하면
메소드 내부의 모든 T가 입력한 해당 데이터 형식으로 변경된다.
제네릭 메소드는 일반 메소드와 다르게 매개변수의 타입을 미리 결정하지 않고, 사용시 결정한다.
제네릭 클래스
사용방식 ↴
한정자 class 클래스이름<형식매개변수>
{
//멤버 변수
//메소드
}
클래스 이름 뒤에 < 와 > 사이에 T를 정의한다.
클래스 내부에는 T 형식으로 사용할 변수들과 반환값들을 설정한다.
클래스 객체 생성 시 T 자리에 사용할 데이터 형식을 입력하면 클래스 내부의 모든 T가 해당 데이터 형식으로 바뀐다.
형식매개변수 제약
형식매개변수 "T"는 이론상 모든 데이터 형식을 대신할 수 있다.
그렇기에 형식매개변수를 사용할 때 원치 않는 데이터 형식을 사용하게 될 때가 생길수도 있다.
이런 상황을 방지하기 위해 특정 조건을 갖춘 형식에만 대응하는 형식매개변수로 제약할 수 있다.
제네릭 메소드, 제네릭 클래스 둘 다 같은 방법으로 제약을 적용할 수 있다.
사용방식 ↴
//where T : ...으로 사용
public class Class<T> where T : class { }
public class Class<T> where T : struct { }
public class Class<T> where T : 부모클래스이름 { }
//등등 많다
아래는 제약들의 목록이다.
제약 | 설명 |
where T : struct | T는 값 형식이어야 한다. |
where T : class | T는 참조 형식이어야 한다. |
where T : new() | T는 반드시 매개변수가 없는 생성자가 있어야 한다. |
where T : 부모클래스이름 | T는 T : ... <- 에 적은 부모(기반)클래스의 자식(파생)클래스여야 한다. |
where T : 인터페이스이름 | T는 T : ... <- 에 적은 인터페이스를 구현해야 한다. |
where T : U | T는 또 다른 형식매개변수 U로 부터 상속받은 클래스여야 한다. |
'C# 기초' 카테고리의 다른 글
[C#] Collections (0) | 2023.10.24 |
---|---|
[C#] ref, in, out 참조에 의한 호출 (0) | 2023.10.23 |
[C#] 값 형식과 참조 형식 (1) | 2023.10.23 |
[C#] 모노 싱글톤 (0) | 2023.10.19 |
[C#] get set 프로퍼티 (1) | 2023.10.10 |