일반화 프로그래밍이란 특수한 개념으로부터 공통된 개념을 찾아 묶는 것을 '일반화(Generalization)'라고 하며, 이를 이용한 프로그래밍 기법을 말합니다. 프로그래밍에서 일반화하는 대상은 '데이터 형식(Type)'입니다.
예를 하나 들어보자면 정수형을 받는 배열이 있다고 합시다.
1
2
3
4
5
6
7
|
void CopyArray(int [] source, int [] target)
{
for(int i = 0; i < source.Length; ++i)
{
source[i] = target[i];
}
}
| cs |
다른 배열에서 데이터를 그대로 복사하는 간단한 함수입니다. 하지만 똑같은 기능을 하는 string타입을 복사하는 함수가 필요합니다.
그럼 위 코드에서 복사해서 int를 string으로 수정해서 사용하는 방법이 있습니다.
하지만 이처럼 기능은 똑같으나 데이터타입에 따라 중복된 코드가 늘어나게되면 가독성도 떨어지고 코드의 양도 방대해지겠지요.
하나의 함수로 여러데이터타입을 받을 수 있게 처리가 이루어진다면 정말 좋겠죠.. 그래서 만들어진게 일반화 프로그래밍입니다.
일반화 프로그래밍은 두곳에서 사용이됩니다. 하나는 메소드, 다른 하나는 클래스입니다.
먼저 메소드먼저 알아보겠습니다.
일반화 메소드는 이름처럼 일반화한 함수를 말합니다. 일반화 메소드는 구체적인 형식의 이름 대신 형식 매개변수가 들어간다는 사실만을
제외하고는 일반함수와 동일합니다.
1
2
3
4
|
한정자 반환형식 메소드이름<형식매개 변수> (매개변수 목록)
{
// 함수 기능 구현
}
| cs |
위 형식처럼 일반화 메소드를 구현할 수 있습니다. 샘플코드로 한번 보시겠습니다.
1
2
3
4
5
6
7
|
void CopyArray<T>(T [] source, T [] target)
{
for(int i = 0; i < source.Length; ++i)
{
source[i] = target[i];
}
}
| cs |
일반화 메소드로 구현하게되면 위와 같은 코드로 변경할 수 있습니다. 여기서 T는 Type, 즉 형식에 해당합니다.
일반화 함수를 호출할때는
1
|
prt.CopyArray<int>(source, target);
| cs |
'<>'안에 어떤 데이터타입을 사용할것인지 명시한 후 호출하시면 됩니다.
두번째로 일반화 클래스에 대해 알아보겠습니다. 일반화 클래스도 형식 매개변수가 있는 것을 제외하면 일반 클래스와 동일합니다.
1
2
3
4
|
Class 클래스이름 <형식 매개변수>
{
// 클래스 구현
}
| cs |
일반화 클래스는 위와 같은 형식으로 선언하여 사용할 수 있습니다.
1
2
3
4
|
class GenericClass<T>
{
public T data { set; get; }
}
| cs |
위와 같이 클래스를 만들 수 있으며,
1
2
3
4
5
6
|
GenericClass<int> intClass = new GenericClass<int>();
intClass.data = 1;
GenericClass<string> stringClass = new GenericClass<string>();
stringClass.data = "HelloWorld";
| cs |
일반화 클래스 한개에 int타입 string타입 타입에 따른 다양한 객체를 생성할 수 있습니다.
여기서 T는 모든 데이터 형식을 대신할 수 있습니다.
그러나 간혹 특정 데이터 형식으로 제한하고자 할때가 있습니다. 이때 where절을 추가해 특정 데이터 형식으로 제한을 둘 수 있답니다.
1
2
3
4
|
Class 클래스이름 <형식 매개변수> where 형식 매개변수 : 데이터형식
{
// 클래스
}
| cs |
코드로 보시면,
1
2
3
4
|
class GenericClass<T> where T : class
{
public T data { set; get; }
}
| cs |
Where T : class 가 추가되었습니다. 이 구문은 T 데이터 형식을 class로 제한하겠다는 의미입니다. 이외에도 제한할 수 있는 여러가지 데이터형식이 있습니다.
Where T
|
struct
|
T는 값형식이어야 합니다
|
Where T
|
class
|
T는 참조 형식이어야 합니다
|
Where T
|
new()
|
T는 반드시 매개변수가 없는 생성자가 있어야 합니다.
|
Where T
|
클래스 이름
|
T는 명시한 기반 클래스의 파생 클래스여야 합니다.
|
Where T
|
인터페이스 이름
|
T는 명시한 인터페이스를 반드시 구현해야 합니다. 인터페이스_이름에는 여러 개의 인터페이스를 명시할 수 도 있습니다.
|
Where T
|
U
|
T는 또 다른 형식 매개 변수 U로부터 상속받은 클래스여야 합니다.
|