Visual Basic의 제네릭 형식
업데이트: 2007년 11월
제네릭 형식은 다양한 데이터 형식에 대해 같은 기능을 수행하도록 조정되는 단일 프로그래밍 요소입니다. 제네릭 클래스나 프로시저를 정의할 때 해당 기능을 수행하려는 각 데이터 형식에 대해 별도의 버전을 정의하지 않아도 됩니다.
유사한 예로 탈부착식 헤드를 가진 드라이버 세트를 들 수 있습니다. 돌려야 하는 나사를 확인한 다음 해당 나사의 올바른 헤드(일자, 십자, 별모양)를 선택합니다. 드라이버 손잡이에 올바른 헤드를 넣은 다음 드라이버와 정확히 같은 기능, 즉 나사를 돌리는 작업을 수행하게 됩니다.
제네릭 도구로서 드라이버 세트
제네릭 형식을 정의할 때 하나 이상의 데이터 형식으로 제네릭 형식을 매개 변수화합니다. 이렇게 하면 코드를 사용하여 데이터 형식을 요구 사항에 맞게 조정할 수 있습니다. 사용자 코드를 사용하여 다양한 데이터 형식에서 작업하는 제네릭 요소의 다양한 프로그래밍 요소를 선언할 수 있습니다. 선언된 요소는 해당 데이터 형식에 관계없이 모두 동일한 논리를 수행합니다.
예를 들어, String처럼 특정 데이터 형식에서 작업하는 큐 클래스를 만들어 사용할 수 있습니다. 다음 예제와 같이 System.Collections.Generic.Queue<T>에서 이러한 클래스를 선언할 수 있습니다.
Public stringQ As New System.Collections.Generic.Queue(Of String)
이제 stringQ를 사용하여 String 값만으로 작업할 수 있습니다. stringQ는 Object 값에 대하여 일반화되지 않고 String에 한정되므로 런타임 바인딩 또는 형식 변환이 발생하지 않습니다. 따라서 실행 시간이 절약되고 런타임 오류가 감소됩니다.
제네릭 형식 사용에 대한 자세한 내용은 방법: 제네릭 클래스 사용을 참조하십시오.
제네릭 클래스의 예
다음 예제에서는 제네릭 클래스에 대한 기본 정의를 보여 줍니다.
Public Class classHolder(Of t)
Public Sub processNewItem(ByVal newItem As t)
Dim tempItem As t
' Insert code that processes an item of data type t.
End Sub
End Class
앞에서 설명한 기본 정의에서 t는 형식 매개 변수, 즉 클래스를 선언할 때 제공하는 데이터 형식에 대한 자리 표시자입니다. 코드의 모든 위치에서 t에 대한 다양한 데이터 형식을 제공하여 다양한 버전의 classHolder를 선언할 수 있습니다. 다음 예제에서는 두 가지 선언을 보여 줍니다.
Public integerClass As New classHolder(Of Integer)
Friend stringClass As New classHolder(Of String)
위의 문에서는 형식 매개 변수를 특정 형식으로 바꾸는 생성된 클래스를 선언합니다. 이 대체는 생성된 클래스 내에서 코드를 통해 전파됩니다. 다음 예제에서는 integerClass의 processNewItem 프로시저 예를 보여 줍니다.
Public Sub processNewItem(ByVal newItem As Integer)
Dim tempItem As Integer
' Inserted code now processes an Integer item.
End Sub
자세한 예제는 방법: 다른 데이터 형식에 동일한 기능을 제공할 수 있는 클래스 정의를 참조하십시오.
적합한 프로그래밍 요소
제네릭 클래스, 구조체, 인터페이스, 프로시저 및 대리자를 정의하고 사용할 수 있습니다. .NET Framework에서는 일반적으로 사용되는 제네릭 요소를 나타내는 다양한 제네릭 클래스, 구조체 및 인터페이스를 정의합니다. System.Collections.Generic 네임스페이스는 사전, 목록, 큐 및 스택을 제공합니다. 사용자 제네릭 요소를 정의하기 전에 해당 요소가 System.Collections.Generic에서 이미 사용 가능한지를 확인합니다.
프로시저는 형식이 아니지만 제네릭 프로시저를 정의하고 사용할 수 있습니다. Visual Basic의 제네릭 프로시저를 참조하십시오.
제네릭 형식의 장점
제네릭 형식은 특정 데이터 형식에서 작동하는 다양한 프로그래밍 요소를 선언하는 기초로 사용됩니다. 제네릭 형식을 대체할 수 있는 형식은 다음과 같습니다.
Object 데이터 형식에서 작용하는 단일 형식
형식별 형식 버전 - 각 버전은 String, Integer 같은 한 가지 특정한 데이터 형식이나 customer 같은 사용자 정의 형식에서 개별적으로 코딩되고 작동합니다.
제네릭 형식은 이러한 대체 형식에 비해 다음과 같은 이점이 있습니다.
형식 안전성. 제네릭 형식은 컴파일 타임 형식 검사를 수행합니다. Object를 기반으로 하는 형식은 모든 데이터 형식을 수용할 수 있으므로 입력 데이터 형식을 받아들일 수 있는지 여부를 확인하는 코드를 작성해야 합니다. 컴파일러는 제네릭 형식을 사용하여 런타임 이전에 형식 불일치를 catch할 수 있습니다.
성능. 각 제네릭 형식이 단일 데이터 형식에 특정되므로 제네릭 형식은 데이터를 boxing 및 unboxing할 필요가 없습니다. Object를 기반으로 하는 작업에서는 입력 데이터 형식을 boxing하여 Object로 변환하고 출력 대상 데이터를 unboxing합니다. Boxing과 unboxing은 성능을 저하시킵니다.
Object를 기반으로 하는 형식은 런타임에 바인딩되므로 해당 멤버에 액세스하려면 런타임에 추가 코드가 필요합니다. 이 또한 성능을 감소시킵니다.
코드 통합. 제네릭 형식의 코드는 한 번만 정의해야 합니다. 형식 관련 버전 집합은 각 버전에서 동일한 코드를 복제해야 합니다. 각 버전이 서로 다른 특정 데이터 형식을 갖는다는 점만 다릅니다. 제네릭 형식을 사용하면 모든 형식 관련 버전이 원본 제네릭 형식에서 생성됩니다.
코드 다시 사용. 특정 데이터 형식에 종속되지 않는 코드는 다양한 제네릭 데이터 형식에서 다시 사용할 수 있습니다. 예상하지 못한 데이터 형식에서 다시 사용할 수 있는 경우도 많습니다.
IDE 지원. 제네릭 형식에서 선언된 생성된 형식을 사용하는 경우 코드를 개발하는 과정에서 IDE(통합 개발 환경)를 통해 많은 지원을 받을 수 있습니다. 예를 들어, IntelliSense™는 생성자 또는 메서드의 인수에 대한 형식별 옵션을 제공할 수 있습니다.
제네릭 알고리즘. 제네릭 형식에는 형식 독립적인 추상 알고리즘을 사용하는 것이 좋습니다. 예를 들어, IComparable 인터페이스를 사용하여 항목을 정렬하는 제네릭 프로시저는 IComparable을 구현하는 데이터 형식에서 사용될 수 있습니다.
제약 조건
제네릭 형식 정의의 코드는 가능한 한 형식 독립적이어야 하지만 제네릭 형식에 제공되는 데이터 형식의 특정 기능이 필요할 수 있습니다. 예를 들어, 정렬 또는 데이터 정렬을 위해 두 항목을 비교하려면 해당 데이터 형식이 IComparable 인터페이스를 구현해야 합니다. 형식 매개 변수에 제약 조건을 추가하여 이 요구 사항을 적용할 수 있습니다.
제약 조건의 예
다음 예제에서는 형식 인수가 IComparable을 구현해야 한다는 제약 조건을 가진 클래스에 대한 기본 정의를 보여 줍니다.
Public Class itemManager(Of t As IComparable)
' Insert code that defines class members.
End Class
후속 코드가 IComparable을 구현하지 않는 형식을 제공하여 itemManager에서 클래스를 생성하려고 시도하면 컴파일러에서 오류를 알립니다.
제약 조건의 유형
제약 조건에서 다음 요구 사항을 조합하여 지정할 수 있습니다.
형식 인수는 하나 이상의 인터페이스를 구현해야 합니다.
형식 인수는 최대 하나의 클래스 형식을 취하거나 최대 하나의 클래스에 상속되어야 합니다.
형식 인수는 개체를 만드는 코드에 액세스할 수 있는 매개 변수 없는 생성자를 노출해야 합니다.
형식 인수는 참조 형식이거나 값 형식이어야 합니다.
여러 요구 사항을 적용해야 하는 경우 중괄호({ }) 안에 쉼표로 구분된 제약 조건 목록을 사용합니다. 액세스 가능한 생성자가 필요한 경우 목록에 New(Visual Basic) 키워드를 포함합니다. 참조 형식이 필요한 경우 Class(Visual Basic) 키워드를 포함하고, 값 형식이 필요한 경우 Structure(Visual Basic) 키워드를 포함합니다.
제약 조건에 대한 자세한 내용은 형식 목록을 참조하십시오.
다중 제약 조건의 예
다음 예제에서는 형식 매개 변수에 제약 조건 목록이 있는 제네릭 클래스의 기본 정의를 보여 줍니다. 이 클래스 인스턴스를 만드는 코드에서 형식 인수는 IComparable 인터페이스와 IDisposable 인터페이스를 모두 구현하고 참조 형식이어야 하며 액세스 가능한 매개 변수 없는 생성자를 노출해야 합니다.
Public Class thisClass(Of t As {IComparable, IDisposable, Class, New})
' Insert code that defines class members.
End Class
중요 용어
제네릭 형식에는 다음과 같은 용어가 사용됩니다.
제네릭 형식. 선언할 때 하나 이상의 데이터 형식을 제공할 클래스, 구조체, 인터페이스, 프로시저 또는 대리자를 정의합니다.
형식 매개 변수. 제네릭 형식 정의에서 형식을 선언할 때 제공하는 데이터 형식에 대한 자리 표시자입니다.
형식 인수. 제네릭 형식에서 생성된 형식을 선언할 때 형식 매개 변수를 대체하는 특정 데이터 형식입니다.
제약 조건. 형식 매개 변수에 대해 제공할 수 있는 형식 인수를 제한하는 조건입니다. 제약 조건을 사용하여 형식 인수가 특정 인터페이스를 구현하거나, 특정 클래스가 되거나, 특정 클래스에서 상속하거나, 액세스 가능한 매개 변수 없는 생성자를 갖거나, 참조 형식 또는 값 형식이 되도록 규정할 수 있습니다. 이러한 제약 조건을 조합하여 사용할 수 있지만 클래스를 최대 하나만 지정할 수 있습니다.
생성된 형식. 형식 매개 변수에 형식 인수를 제공하여 제네릭 형식에서 선언된 클래스, 구조체, 인터페이스, 프로시저 또는 대리자입니다.