Typy ogólne w Visual Basic (Visual Basic)

Typ ogólny to pojedynczy element programowania, który dostosowuje się do wykonywania tych samych funkcji dla różnych typów danych. Podczas definiowania klasy ogólnej lub procedury nie trzeba definiować oddzielnej wersji dla każdego typu danych, dla którego można chcieć wykonać tę funkcję.

Analogią jest śrubokręt zestaw z wymiennymi głowicami. Sprawdzasz śrubę, którą należy obrócić i wybrać prawidłową głowicę dla tej śruby (szczelinowe, skrzyżowane, z gwiazdą). Po włożeniu prawidłowej głowicy do uchwytu śrubokręta wykonujesz dokładnie tę samą funkcję za pomocą śrubokręta, a mianowicie obracając śrubę.

Diagram of a screwdriver set with different heads.

Podczas definiowania typu ogólnego parametryzujesz go za pomocą co najmniej jednego typu danych. Dzięki temu można dostosować typy danych do swoich wymagań przy użyciu kodu. Kod może deklarować kilka różnych elementów programowania od elementu ogólnego, z których każdy działa na innym zestawie typów danych. Jednak zadeklarowane elementy wykonują identyczną logikę, niezależnie od typów danych, z których korzystają.

Na przykład możesz utworzyć klasę kolejki i użyć jej, która działa na określonym typie danych, takim jak String. Taką klasę można zadeklarować z System.Collections.Generic.Queue<T>klasy , jak pokazano w poniższym przykładzie.

Public stringQ As New System.Collections.Generic.Queue(Of String)

Teraz możesz użyć stringQ polecenia , aby pracować wyłącznie z wartościami String . Ponieważ stringQ jest specyficzny dla String zamiast uogólniać wartości Object , nie masz późnego powiązania ani konwersji typu. Pozwala to zaoszczędzić czas wykonywania i skrócić błędy czasu wykonywania.

Aby uzyskać więcej informacji na temat używania typu ogólnego, zobacz How to: Use a Generic Class (Instrukcje: używanie klasy ogólnej).

Przykład klasy ogólnej

Poniższy przykład przedstawia definicję szkieletu klasy ogólnej.

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

W poprzednim szkieletie t jest parametrem typu, czyli symbolem zastępczym dla typu danych, który podajesz podczas deklarowania klasy. W innym miejscu w kodzie można zadeklarować różne wersje classHolder , podając różne typy danych dla elementu t. W poniższym przykładzie przedstawiono dwie takie deklaracje.

Public integerClass As New classHolder(Of Integer)
Friend stringClass As New classHolder(Of String)

Poprzednie instrukcje deklarują skonstruowane klasy, w których określony typ zastępuje parametr typu. To zastąpienie jest propagowane w całym kodzie w skonstruowanej klasie. W poniższym przykładzie pokazano, processNewItem jak wygląda procedura w pliku integerClass.

Public Sub processNewItem(ByVal newItem As Integer)
    Dim tempItem As Integer
    ' Inserted code now processes an Integer item.
End Sub

Aby zapoznać się z bardziej kompletnym przykładem, zobacz How to: Define a Class That Can Provide Identical Functionality on Different Data Types (Instrukcje: definiowanie klasy, która może zapewniać identyczne funkcje dla różnych typów danych).

Kwalifikujące się elementy programowania

Można definiować i używać klas ogólnych, struktur, interfejsów, procedur i delegatów. Należy pamiętać, że program .NET Framework definiuje kilka klas ogólnych, struktur i interfejsów, które reprezentują powszechnie używane elementy ogólne. System.Collections.Generic Przestrzeń nazw udostępnia słowniki, listy, kolejki i stosy. Przed zdefiniowaniem własnego elementu ogólnego sprawdź, czy jest już dostępny w pliku System.Collections.Generic.

Procedury nie są typami, ale można definiować i używać procedur ogólnych. Zobacz Ogólne procedury w Visual Basic.

Zalety typów ogólnych

Typ ogólny służy jako podstawa do deklarowania kilku różnych elementów programowania, z których każdy działa na określonym typie danych. Alternatywy dla typu ogólnego to:

  1. Pojedynczy typ działający na typie Object danych.

  2. Zestaw wersji specyficznych dla typu typu, każda wersja indywidualnie kodowana i działająca na jednym określonym typie danych, takim jak String, Integerlub typ zdefiniowany przez użytkownika, taki jak customer.

Typ ogólny ma następujące zalety w stosunku do następujących alternatyw:

  • Wpisz Sejf ty. Typy ogólne wymuszają sprawdzanie typów w czasie kompilacji. Typy oparte na akceptowaniu Object dowolnego typu danych i musisz napisać kod, aby sprawdzić, czy typ danych wejściowych jest akceptowalny. W przypadku typów ogólnych kompilator może przechwytywać niezgodności typów przed czasem wykonywania.

  • Wydajność. Typy ogólne nie muszą zawierać pól i rozpadawać danych, ponieważ każdy z nich jest wyspecjalizowany dla jednego typu danych. Operacje oparte na Object typach danych wejściowych muszą być box, aby przekonwertować je na Object dane wyjściowe i rozpatywać je. Boxing i unboxing zmniejszają wydajność.

    Typy oparte na Object są również ograniczone późno, co oznacza, że uzyskiwanie dostępu do ich elementów członkowskich wymaga dodatkowego kodu w czasie wykonywania. Zmniejsza to również wydajność.

  • Konsolidacja kodu. Kod w typie ogólnym musi być zdefiniowany tylko raz. Zestaw wersji typu musi replikować ten sam kod w każdej wersji, a jedyną różnicą jest określony typ danych dla tej wersji. W przypadku typów ogólnych wszystkie wersje specyficzne dla typu są generowane na podstawie oryginalnego typu ogólnego.

  • Ponowne użycie kodu. Kod, który nie zależy od określonego typu danych, może być ponownie używany z różnymi typami danych, jeśli jest ogólny. Często można użyć go ponownie nawet w przypadku typu danych, który nie został pierwotnie przewidywany.

  • Obsługa środowiska IDE. W przypadku używania skonstruowanego typu zadeklarowanego z typu ogólnego zintegrowane środowisko projektowe (IDE) może zapewnić większą obsługę podczas opracowywania kodu. Na przykład funkcja IntelliSense może wyświetlać opcje specyficzne dla typu argumentu konstruktora lub metody.

  • Algorytmy ogólne. Algorytmy abstrakcyjne niezależne od typu są dobrymi kandydatami do typów ogólnych. Na przykład ogólna procedura, która sortuje elementy przy użyciu interfejsu IComparable , może być używana z dowolnym typem danych, który implementuje IComparableelement .

Ograniczenia

Mimo że kod w definicji typu ogólnego powinien być tak niezależny od typu, jak to możliwe, może być konieczne wymaganie określonej możliwości dowolnego typu danych dostarczonego do typu ogólnego. Jeśli na przykład chcesz porównać dwa elementy w celu sortowania lub sortowania, ich typ danych musi implementować IComparable interfejs. To wymaganie można wymusić, dodając ograniczenie do parametru typu.

Przykład ograniczenia

W poniższym przykładzie przedstawiono definicję szkieletu klasy z ograniczeniem, które wymaga, aby argument typu zaimplementował IComparableelement .

Public Class itemManager(Of t As IComparable)
    ' Insert code that defines class members.
End Class

Jeśli kolejny kod próbuje skonstruować klasę z itemManager podawania typu, który nie implementuje IComparable, kompilator sygnalizuje błąd.

Typy ograniczeń

Ograniczenie może określać następujące wymagania w dowolnej kombinacji:

  • Argument typu musi implementować co najmniej jeden interfejs

  • Argument typu musi być typu lub dziedziczyć z co najwyżej jednej klasy

  • Argument typu musi uwidocznić konstruktor bez parametrów dostępny dla kodu, który tworzy na jego podstawie obiekty

  • Argument typu musi być typem odwołania lub musi być typem wartości

Jeśli musisz narzucić więcej niż jedno wymaganie, należy użyć listy ograniczeń rozdzielanych przecinkami wewnątrz nawiasów klamrowych ({ }). Aby wymagać dostępnego konstruktora, należy dołączyć słowo kluczowe New Operator na liście. Aby wymagać typu odwołania, należy dołączyć Class słowo kluczowe ; aby wymagać typu wartości, należy dołączyć Structure słowo kluczowe.

Aby uzyskać więcej informacji na temat ograniczeń, zobacz Lista typów.

Przykład wielu ograniczeń

W poniższym przykładzie przedstawiono definicję szkieletu klasy ogólnej z listą ograniczeń na parametrze type. W kodzie, który tworzy wystąpienie tej klasy, argument typu musi implementować zarówno interfejsy, jak IComparable i IDisposable , być typem odwołania i uwidaczniać dostępny konstruktor bez parametrów.

Public Class thisClass(Of t As {IComparable, IDisposable, Class, New})
    ' Insert code that defines class members.
End Class

Ważne terminy

Typy ogólne zawierają i używają następujących terminów:

  • Typ ogólny. Definicja klasy, struktury, interfejsu, procedury lub delegata, dla którego należy podać co najmniej jeden typ danych podczas deklarowania.

  • Wpisz parametr. W definicji typu ogólnego symbol zastępczy dla typu danych, który podajesz podczas deklarowania typu.

  • Wpisz argument. Określony typ danych, który zastępuje parametr typu podczas deklarowania skonstruowanego typu z typu ogólnego.

  • Ograniczenie. Warunek dla parametru typu, który ogranicza argument typu, który można podać dla niego. Ograniczenie może wymagać, aby argument typu musiał zaimplementować określony interfejs, być lub dziedziczyć z określonej klasy, mieć dostępny konstruktor bez parametrów lub być typem odwołania lub typem wartości. Te ograniczenia można połączyć, ale można określić co najwyżej jedną klasę.

  • Skonstruowany typ. Klasa, struktura, interfejs, procedura lub delegat zadeklarowany z typu ogólnego przez podanie argumentów typu dla parametrów typu.

Zobacz też