Share via


Allmänna typer i Visual Basic (Visual Basic)

En allmän typ är ett enda programmeringselement som anpassas för att utföra samma funktioner för en mängd olika datatyper. När du definierar en allmän klass eller procedur behöver du inte definiera en separat version för varje datatyp som du kanske vill utföra den funktionen för.

En analogi är en skruvmejseluppsättning med flyttbara huvuden. Du inspekterar skruven du behöver för att vända och välja rätt huvud för den skruven (slits, korsad, stjärnmärkt). När du sätter in rätt huvud i skruvmejselhandtaget utför du exakt samma funktion med skruvmejseln, nämligen att vrida skruven.

Diagram of a screwdriver set with different heads.

När du definierar en allmän typ kan du parametrisera den med en eller flera datatyper. På så sätt kan du använda kod för att anpassa datatyperna efter dess krav. Koden kan deklarera flera olika programmeringselement från det allmänna elementet, var och en som agerar på en annan uppsättning datatyper. Men de deklarerade elementen utför alla samma logik, oavsett vilka datatyper de använder.

Du kanske till exempel vill skapa och använda en köklass som fungerar på en viss datatyp, Stringtill exempel . Du kan deklarera en sådan klass från System.Collections.Generic.Queue<T>, som i följande exempel visas.

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

Du kan nu använda stringQ för att arbeta uteslutande med String värden. Eftersom stringQ är specifikt för i stället för String att generaliseras för Object värden, har du inte sen bindning eller typkonvertering. Detta sparar körningstid och minskar körningsfel.

Mer information om hur du använder en allmän typ finns i Så här använder du en allmän klass.

Exempel på en allmän klass

I följande exempel visas en skelettdefinition av en generisk klass.

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

I föregående skelett t är en typparameter, det vill säga en platshållare för en datatyp som du anger när du deklarerar klassen. På andra ställen i koden kan du deklarera olika versioner av classHolder genom att ange olika datatyper för t. I följande exempel visas två sådana deklarationer.

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

Föregående instruktioner deklarerar konstruerade klasser, där en specifik typ ersätter typparametern. Den här ersättningen sprids i koden i den konstruerade klassen. I följande exempel visas hur proceduren processNewItem ser ut i integerClass.

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

Ett mer komplett exempel finns i Så här definierar du en klass som kan tillhandahålla identiska funktioner för olika datatyper.

Berättigade programmeringselement

Du kan definiera och använda allmänna klasser, strukturer, gränssnitt, procedurer och ombud. Observera att .NET Framework definierar flera generiska klasser, strukturer och gränssnitt som representerar vanliga allmänna element. Namnområdet System.Collections.Generic innehåller ordlistor, listor, köer och staplar. Innan du definierar ditt eget generiska element ska du se om det redan är tillgängligt i System.Collections.Generic.

Procedurer är inte typer, men du kan definiera och använda allmänna procedurer. Se Allmänna procedurer i Visual Basic.

Fördelar med generiska typer

En allmän typ fungerar som grund för att deklarera flera olika programmeringselement, som var och en fungerar med en specifik datatyp. Alternativen till en allmän typ är:

  1. En enda typ som körs på Object datatypen.

  2. En uppsättning typspecifika versioner av typen, varje version som kodas individuellt och körs på en specifik datatyp, till Stringexempel , Integereller en användardefinierad typ, till exempel customer.

En allmän typ har följande fördelar jämfört med dessa alternativ:

  • Skriv Valv ty. Allmänna typer tillämpar kompileringstidstypkontroll. Typer som baseras på Object accepterar alla datatyper och du måste skriva kod för att kontrollera om en indatatyp är acceptabel. Med generiska typer kan kompilatorn fånga typmatchningar före körningstid.

  • Prestanda. Generiska typer behöver inte boxa och ta bort data, eftersom var och en är specialiserad på en datatyp. Åtgärder som baseras på Object måste boxa indatatyper för att konvertera dem till Object och ta bort data som är avsedda för utdata. Boxning och avboxning minskar prestandan.

    Typer som baseras på Object är också senbundna, vilket innebär att åtkomst till deras medlemmar kräver extra kod vid körning. Detta minskar också prestandan.

  • Kodkonsolidering. Koden i en allmän typ måste bara definieras en gång. En uppsättning typspecifika versioner av en typ måste replikera samma kod i varje version, där den enda skillnaden är den specifika datatypen för den versionen. Med generiska typer genereras alla typspecifika versioner från den ursprungliga generiska typen.

  • Återanvänd kod. Kod som inte är beroende av en viss datatyp kan återanvändas med olika datatyper om den är generisk. Du kan ofta återanvända den även med en datatyp som du inte förutsade från början.

  • IDE-support. När du använder en konstruerad typ som deklarerats från en allmän typ kan den integrerade utvecklingsmiljön (IDE) ge dig mer stöd medan du utvecklar koden. IntelliSense kan till exempel visa de typspecifika alternativen för ett argument till en konstruktor eller metod.

  • Allmänna algoritmer. Abstrakta algoritmer som är typoberoende är bra kandidater för generiska typer. En allmän procedur som sorterar objekt med hjälp av IComparable gränssnittet kan till exempel användas med alla datatyper som implementerar IComparable.

Krav

Även om koden i en allmän typdefinition ska vara så typoberoende som möjligt, kan du behöva kräva en viss funktion av alla datatyper som tillhandahålls till den allmänna typen. Om du till exempel vill jämföra två objekt för sortering eller sortering måste deras datatyp implementera IComparable gränssnittet. Du kan tillämpa det här kravet genom att lägga till en begränsning i typparametern.

Exempel på en begränsning

I följande exempel visas en skelettdefinition av en klass med en begränsning som kräver typargumentet för att implementera IComparable.

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

Om efterföljande kod försöker konstruera en klass från itemManager att ange en typ som inte implementerar IComparable, signalerar kompilatorn ett fel.

Typer av begränsningar

Din begränsning kan ange följande krav i valfri kombination:

  • Typargumentet måste implementera ett eller flera gränssnitt

  • Typargumentet måste vara av typen eller ärver från högst en klass

  • Typargumentet måste exponera en parameterlös konstruktor som är tillgänglig för koden som skapar objekt från den

  • Typargumentet måste vara en referenstyp, eller så måste det vara en värdetyp

Om du behöver införa fler än ett krav använder du en kommaavgränsad begränsningslista i klammerparenteser ({ }). Om du vill kräva en tillgänglig konstruktor tar du med nyckelordet Ny operator i listan. Om du vill kräva en referenstyp inkluderar du nyckelordet Class . Om du vill kräva en värdetyp inkluderar du nyckelordet Structure .

Mer information om begränsningar finns i Typlista.

Exempel på flera begränsningar

I följande exempel visas en skelettdefinition av en generisk klass med en begränsningslista för typparametern. I koden som skapar en instans av den här klassen måste typargumentet implementera både gränssnitten IComparable och IDisposable , vara en referenstyp, och exponera en tillgänglig parameterlös konstruktor.

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

Viktiga termer

Generiska typer introducerar och använder följande termer:

  • Allmän typ. En definition av en klass, struktur, gränssnitt, procedur eller ombud som du anger minst en datatyp för när du deklarerar den.

  • Typparameter. I en allmän typdefinition är en platshållare för en datatyp som du anger när du deklarerar typen.

  • Skriv Argument. En specifik datatyp som ersätter en typparameter när du deklarerar en konstruerad typ från en allmän typ.

  • Villkor. Ett villkor för en typparameter som begränsar det typargument som du kan ange för den. En begränsning kan kräva att typargumentet måste implementera ett visst gränssnitt, vara eller ärva från en viss klass, ha en tillgänglig parameterlös konstruktor eller vara en referenstyp eller en värdetyp. Du kan kombinera dessa begränsningar, men du kan ange högst en klass.

  • Konstruerad typ. En klass, struktur, gränssnitt, procedur eller ombud som deklarerats från en allmän typ genom att ange typargument för sina typparametrar.

Se även