Generic

[C#] Generic 이란?

제너릭이란 데이터의 타입을 일반화하는 것을 의미합니다.

1
2
3
4
public void Method<T> (T parameter1, T parameter2)
{
---내용
}

원래라면 자료형에 관계없이 동일한 작업을 진행해야하는 메소드가 필요할 경우 오버라이딩을 통해 리턴 형식이 다르거나, 다른 종류와 개수의 파라미터를 가지는 메소드를 정의해주어야 했습니다.

1
2
3
4
5
6
7
8
9
10
11
public void Print(int num){
Console.WriteLine($"{num}");
}

public void Print(string str){
Console.WriteLine($"{str}");
}

public void Print(float num){
Console.WriteLine($"{num}");
}

같은 메소드를 여러번 정의하는 것은 여간 번거로운 일이 아닙니다.

그렇기 때문에 어떤 형식이든 이용할 수 있도록 제너릭으로 일반화 메소드를 정의해주면 간편해집니다.

1
2
3
public void Print<T> (T Parameter){
Console.WriteLine($"{Parameter}");
}

제너릭은 코드를 재사용할 때, 형식의 안전성과 성능을 최대화합니다.

제너릭은 제너릭 클래스로 가장 많이 활용됩니다.

각 인스턴스에서 클래스에 있는 모든 T는 컴파일할 때 제너릭 형식을 의미하는 메타데이터가 생성됩니다.

그 후 런타임에 메타데이터를 확인하고 특수화된 제너릭 클래스를 생성합니다.

이 때 사용된 형식이 값 형식인지 참조 형식인지에 따라 제너릭 클래스를 생성하는 방식이 달라집니다.


값 형식일 경우

만약 정수를 사용한다면 매개 변수를 정수로 적절히 대체하여 특수화된 버전의 클래스를 생성합니다.

프로그램 코드에서 해당 클래스를 정수를 이용하여 다시 사용한다면

이전에 생성했던 특수화 클래스를 다시 사용합니다.

하지만 다른 값 형식이 들어온다면,

다른 버전을 생성하여 적절한 위치에 다른 값 형식을 대체합니다.

참조 형식일 경우

런타임에서 MSIL의 매개 변수를 개체 참조로 대체하여 특수화된 제너릭 형식을 만듭니다.

이후 참조 형식과 관계없이 생성된 형식이 인스턴스화될 때마다
런타임에서 이전에 만든 특수화된 버전의 제너릭 형식을 재사용합니다.

재사용할 때는 이미 생성된 클래스의 인스턴스를 생성하여 변수가 인스턴스를 참조하게 됩니다.