일반화 프로그래밍(Generic Programming)은 타입에 무관하게 알고리즘을 작성하는 프로그래밍 기법입니다. 실제 타입은 매개변수를 통해 전달됩니다.
일반화 프로그래밍을 이용하면 코드의 재사용성을 극대화 시킬 수 있습니다.
기존에 작성하던 방식은 타입에 강하게 종속되어 있기 때문에 알고리즘이 동일하더라도 타입을 전부 바꿔서 작성해야 했지만, 일반화 프로그래밍을 이용하면 그러지 않아도 됩니다.

C#은 일반화 프로그래밍을 제너릭(Generic)으로 제공하고 있습니다.
Generic 사용법은 <>꺽새 안에 T를 넣으면 됩니다.
T는 타입 매개변수입니다. 타입 파리미터를 사용하는 것은 청사진을 정의하는 것과 같은데, 타입 파리미터는 런타임에 전달된 타입 인수로 대치됩니다.
타입 파라미터는 클래스, 인터페이스, 대리자, 메소드에 붙일 수 있습니다. 이 외에는 제너릭을 사용할 수 없습니다.

아무 타입이나 전달되지 못하도록 제약(Constraint)을 걸 수 있습니다.

위 상황처럼 오류를 초래할 수 있습니다. 제약을 걸면 아래처럼 안전해집니다!

제약의 종류
where T : struct
T는 값 형식이어야 합니다.
where T : class
T는 참조 형식이어야 합니다.
where T : unmanaged
형식 인수는 참조 형식일 수 없으며, 모든 중첩 수준에서 참조 형식 멤버를 포함할 수 없습니다.
where T : new()
T는 반드시 매개 변수가 없는 생성자가 있어야 합니다.
where T : 기본(부모)클래스 이름
T는 명시한 기본(부모) 클래스의 파생 클래스여야 합니다.

where T : 인터페이스_이름
T는 명시한 인터페이스를 반드시 구현해야 합니다.
인터페이스 이름에는 여러 개의 인터페이스를 명시할 수도 있습니다.
where T :U
T는 또 다른 형식 매개 변수 U로부터 상속받은 클래스여야 합니다.