Udostępnij za pośrednictwem


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 wielu 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 zestaw śrubokrętów z wymiennymi końcówkami. Najpierw sprawdzasz śrubę i wybierasz odpowiednią końcówkę (płaski, krzyżakowy, gwiazdkowy). 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.

Diagram śrubokręta z różnymi głowicami.

Podczas definiowania typu ogólnego parametryzujesz go za pomocą co najmniej jednego typu danych. Parametry typu umożliwiają kodowi dostosowanie typów danych do swoich wymagań. 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 chcieć utworzyć klasę kolejki, która działa na określonym typie danych, takim jak String. Taką klasę można zadeklarować z System.Collections.Generic.Queue<T>, jak pokazano w poniższym przykładzie.

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

Teraz możesz używać stringQ do pracy wyłącznie z wartościami String. Ze względu na to, że stringQ jest specyficzna dla String, zamiast być ogólna dla wartości Object, nie ma późnego powiązania ani konwersji typu. Typy ogólne oszczędzają czas wykonywania i zmniejszają ilość błędów czasu wykonywania.

Aby uzyskać więcej informacji na temat używania typu ogólnego, zobacz Jak używać klasy ogólnej.

Przykład klasy ogólnej

Poniższy przykład przedstawia definicję szkieletu klasy generycznej.

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 typu danych, który podaje się podczas deklarowania klasy. W innym miejscu kodu można zadeklarować różne wersje classHolder, podając różne typy danych dla 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 oświadczenia deklarują zdefiniowane 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, jak wygląda procedura processNewItem w 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 Jak: Zdefiniować klasę, która może zapewnić identyczną funkcjonalność 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. Platforma .NET definiuje kilka ogólnych klas, struktur i interfejsów, które reprezentują powszechnie używane elementy ogólne. Przestrzeń nazw System.Collections.Generic udostępnia słowniki, listy, kolejki i stosy. Przed zdefiniowaniem własnego elementu ogólnego sprawdź, czy jest już dostępny w System.Collections.Generic.

Procedury nie są typami, ale można definiować i używać procedur ogólnych. Zobacz procedury ogólne w języku 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 danych Object.
  2. Zestaw wersji typu specyficznych dla. Każda wersja jest oddzielnie kodowana i działa 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:

  • Bezpieczeństwo Typów. Typy ogólne wymuszają sprawdzanie typów w czasie kompilacji. Typy oparte na Object akceptują dowolny typ 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ą opakowywać i rozpakowywać danych, ponieważ każdy z nich jest wyspecjalizowany dla jednego rodzaju danych. Operacje oparte na Object muszą opakowywać typy danych wejściowych, aby przekonwertować je na Object i odpakować dane przeznaczone do wyjścia. Boxing i unboxing pogarszają wydajność. Typy oparte na Object są również wiązane dynamicznie, co oznacza, że uzyskiwanie dostępu do ich członów wymaga dodatkowego kodu w czasie wykonywania. Konwersje typów również zmniejszają wydajność.
  • Konsolidacja kodu. Kod w typie ogólnym musi być zdefiniowany tylko raz. Zestaw wersji konkretnego typu musi replikować ten sam kod w każdej wersji, a jedyną różnicą jest konkretny typ danych dla danej 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żywać go ponownie nawet w przypadku typu danych, którego pierwotnie nie przewidywaliśmy.
  • Obsługa środowiska IDE. Jeśli używasz typu stworzonego na bazie typu ogólnego, zintegrowane środowisko programistyczne (IDE) może zapewnić większe wsparcie 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 sortowania elementów przy użyciu interfejsu IComparable może być używana z dowolnym typem danych, który implementuje IComparable.

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 do sortowania lub porządkowania, ich typ danych musi zaimplementować interfejs IComparable. To wymaganie można wymusić, dodając ograniczenie do parametru typu.

Przykład ograniczenia

Poniższy przykład przedstawia definicję szkieletu klasy z ograniczeniem, które wymaga, aby argument typu zaimplementował IComparable.

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 dostarczając typ, 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
  • Typ argumentu musi być typem odwołania lub musi być typem wartości

Kod języka C# może zadeklarować, że argument typu musi być typem niezarządzanym . Język Visual Basic wymusza to ograniczenie dla kodu języka Visual Basic, który używa typu ogólnego lub metody zdefiniowanej za pomocą tego ograniczenia (w języku C#). Nie można jednak zadeklarować ograniczenia unmanaged dla parametru typu w Visual Basic.

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

Aby uzyskać więcej informacji na temat ograniczeń, zobacz Type List.

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 IComparable, jak i IDisposable, być typem odwołania i uwidocznić 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.
  • parametr typu. 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 implementować określony interfejs, 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ę bazową.
  • typ zbudowany. Klasa, struktura, interfejs, procedura lub delegat z typu ogólnego zadeklarowany przez podanie argumentów typu dla parametrów typu.

Zobacz też