Generics in .NET

Met generics kunt u een methode, klasse, structuur of interface aanpassen aan het exacte gegevenstype waarop deze fungeert. In plaats van bijvoorbeeld de Hashtable klasse te gebruiken, waarmee sleutels en waarden van elk type kunnen worden gebruikt, kunt u de Dictionary<TKey,TValue> algemene klasse gebruiken en de typen opgeven die zijn toegestaan voor de sleutel en de waarde. De voordelen van generics zijn de hergebruik van code en typeveiligheid.

Algemene functies definiëren en gebruiken

Generics zijn klassen, structuren, interfaces en methoden met tijdelijke aanduidingen (typeparameters) voor een of meer typen die ze opslaan of gebruiken. Een algemene verzamelingsklasse kan een typeparameter gebruiken als tijdelijke aanduiding voor het type objecten dat wordt opgeslagen; de typeparameters worden weergegeven als de typen velden en de parametertypen van de methoden. Een algemene methode kan de typeparameter gebruiken als het type retourwaarde of als het type van een van de formele parameters. De volgende code illustreert een eenvoudige algemene klassedefinitie.

generic<typename T>
public ref class Generics
{
public:
    T Field;
};
public class Generic<T>
{
    public T Field;
}
Public Class Generic(Of T)
    Public Field As T

End Class

Wanneer u een exemplaar van een algemene klasse maakt, geeft u de werkelijke typen op die moeten worden vervangen door de typeparameters. Hiermee wordt een nieuwe algemene klasse ingesteld, aangeduid als een samengestelde algemene klasse, waarbij de gekozen typen overal worden vervangen door de typeparameters. Het resultaat is een typeveilige klasse die is afgestemd op uw keuze van typen, zoals de volgende code illustreert.

static void Main()
{
    Generics<String^>^ g = gcnew Generics<String^>();
    g->Field = "A string";
    //...
    Console::WriteLine("Generics.Field           = \"{0}\"", g->Field);
    Console::WriteLine("Generics.Field.GetType() = {0}", g->Field->GetType()->FullName);
}
public static void Main()
{
    Generic<string> g = new Generic<string>();
    g.Field = "A string";
    //...
    Console.WriteLine("Generic.Field           = \"{0}\"", g.Field);
    Console.WriteLine("Generic.Field.GetType() = {0}", g.Field.GetType().FullName);
}
Public Shared Sub Main()
    Dim g As New Generic(Of String)
    g.Field = "A string"
    '...
    Console.WriteLine("Generic.Field           = ""{0}""", g.Field)
    Console.WriteLine("Generic.Field.GetType() = {0}", g.Field.GetType().FullName)
End Sub

Algemene terminologie

De volgende termen worden gebruikt voor het bespreken van generics in .NET:

  • Een algemene typedefinitie is een klasse-, structuur- of interfacedeclaratie die fungeert als een sjabloon, met tijdelijke aanduidingen voor de typen die deze kan bevatten of gebruiken. De klasse kan bijvoorbeeld System.Collections.Generic.Dictionary<TKey,TValue> twee typen bevatten: sleutels en waarden. Omdat een algemene typedefinitie alleen een sjabloon is, kunt u geen exemplaren maken van een klasse, structuur of interface die een algemene typedefinitie is.

  • Algemene typeparameters of typeparameters zijn de tijdelijke aanduidingen in een algemene type- of methodedefinitie. Het System.Collections.Generic.Dictionary<TKey,TValue> algemene type heeft twee typeparameters en TKeyTValue, die de typen sleutels en waarden vertegenwoordigen.

  • Een samengesteld algemeen type of samengesteld type is het resultaat van het opgeven van typen voor de algemene typeparameters van een algemene typedefinitie.

  • Een algemeen typeargument is elk type dat wordt vervangen door een algemene typeparameter.

  • Het algemene type algemene term omvat zowel samengestelde typen als algemene typedefinities.

  • Met covariantie en contravariantie van algemene typeparameters kunt u samengestelde algemene typen gebruiken waarvan de typeargumenten meer afgeleide (covariantie) of minder afgeleide (contravariantie) zijn dan een samengesteld doeltype. Covariantie en contravariantie worden gezamenlijk aangeduid als variantie. Zie Covariantie en Contravariantie voor meer informatie.

  • Beperkingen zijn limieten voor algemene typeparameters. U kunt bijvoorbeeld een typeparameter beperken tot typen die de System.Collections.Generic.IComparer<T> algemene interface implementeren om ervoor te zorgen dat exemplaren van het type kunnen worden geordend. U kunt ook typeparameters beperken tot typen met een bepaalde basisklasse, die een parameterloze constructor hebben of die verwijzingstypen of waardetypen zijn. Gebruikers van het algemene type kunnen geen argumenten vervangen die niet voldoen aan de beperkingen.

  • Een algemene methodedefinitie is een methode met twee parameterlijsten: een lijst met algemene typeparameters en een lijst met formele parameters. Typeparameters kunnen worden weergegeven als het retourtype of als de typen van de formele parameters, zoals in de volgende code wordt weergegeven.

generic<typename T>
T Generic(T arg)
{
    T temp = arg;
    //...
    return temp;
}
T Generic<T>(T arg)
{
    T temp = arg;
    //...
    return temp;
}
Function Generic(Of T)(ByVal arg As T) As T
    Dim temp As T = arg
    '...
    Return temp
End Function

Algemene methoden kunnen worden weergegeven op algemene of niet-genrische typen. Het is belangrijk te weten dat een methode niet algemeen is omdat deze deel uitmaakt van een algemeen type, of zelfs omdat deze formele parameters heeft waarvan de typen de algemene parameters van het insluittype zijn. Een methode is alleen algemeen als deze een eigen lijst met typeparameters heeft. In de volgende code is alleen de methode G algemeen.

ref class A
{
    generic<typename T>
    T G(T arg)
    {
        T temp = arg;
        //...
        return temp;
    }
};
generic<typename T>
ref class Generic
{
    T M(T arg)
    {
        T temp = arg;
        //...
        return temp;
    }
};
class A
{
    T G<T>(T arg)
    {
        T temp = arg;
        //...
        return temp;
    }
}
class Generic<T>
{
    T M(T arg)
    {
        T temp = arg;
        //...
        return temp;
    }
}
Class A
    Function G(Of T)(ByVal arg As T) As T
        Dim temp As T = arg
        '...
        Return temp
    End Function
End Class
Class Generic(Of T)
    Function M(ByVal arg As T) As T
        Dim temp As T = arg
        '...
        Return temp
    End Function
End Class

Voor- en nadelen van generics

Er zijn veel voordelen voor het gebruik van algemene verzamelingen en gemachtigden:

  • Typeveiligheid. Generics verschuiven de last van typeveiligheid van u naar de compiler. U hoeft geen code te schrijven om te testen op het juiste gegevenstype, omdat deze tijdens het compileren wordt afgedwongen. De behoefte aan type casten en de mogelijkheid van runtimefouten wordt verminderd.

  • Minder code en code worden eenvoudiger opnieuw gebruikt. U hoeft geen gegevens over te nemen van een basistype en leden te overschrijven. De is bijvoorbeeld LinkedList<T> gereed voor direct gebruik. U kunt bijvoorbeeld een gekoppelde lijst met tekenreeksen maken met de volgende variabeledeclaratie:

    LinkedList<String^>^ llist = gcnew LinkedList<String^>();
    
    LinkedList<string> llist = new LinkedList<string>();
    
    Dim llist As New LinkedList(Of String)()
    
  • Betere prestaties. Algemene verzamelingstypen presteren over het algemeen beter voor het opslaan en bewerken van waardetypen, omdat de waardetypen niet hoeven te worden gebruikt.

  • Algemene gemachtigden maken typeveilige callbacks mogelijk zonder dat u meerdere gemachtigdenklassen hoeft te maken. Met de Predicate<T> algemene gemachtigde kunt u bijvoorbeeld een methode maken die uw eigen zoekcriteria voor een bepaald type implementeert en uw methode gebruikt met methoden van het Array type, zoals Find, FindLasten FindAll.

  • Generics stroomlijnen dynamisch gegenereerde code. Wanneer u generics gebruikt met dynamisch gegenereerde code, hoeft u het type niet te genereren. Dit verhoogt het aantal scenario's waarin u lichtgewicht dynamische methoden kunt gebruiken in plaats van volledige assembly's te genereren. Zie Voor meer informatie : Dynamische methoden definiëren en uitvoeren en DynamicMethod.

Hier volgen enkele beperkingen van algemene functies:

  • Algemene typen kunnen worden afgeleid van de meeste basisklassen, zoals MarshalByRefObject (en beperkingen kunnen worden gebruikt om te vereisen dat algemene typeparameters zijn afgeleid van basisklassen, zoals MarshalByRefObject). .NET biedt echter geen ondersteuning voor contextgebonden algemene typen. Een algemeen type kan worden afgeleid van ContextBoundObject, maar een exemplaar van dat type probeert te maken, veroorzaakt een TypeLoadException.

  • Opsommingen kunnen geen algemene typeparameters hebben. Een opsomming kan alleen per ongeluk algemeen zijn (bijvoorbeeld omdat deze is genest in een algemeen type dat is gedefinieerd met behulp van Visual Basic, C# of C++). Zie Opsommingen in Common Type System voor meer informatie.

  • Lichtgewicht dynamische methoden kunnen niet algemeen zijn.

  • In Visual Basic, C# en C++, kan een geneste type dat is ingesloten in een algemeen type, niet worden geïnstantieerd, tenzij er typen zijn toegewezen aan de typeparameters van alle typen insluiten. Een andere manier om dit te zeggen, is dat een geneste type dat wordt gedefinieerd met behulp van deze talen, de typeparameters van alle bijbehorende insluittypen bevat. Hierdoor kunnen de typeparameters van insluittypen worden gebruikt in de liddefinities van een genest type. Zie 'Geneste typen' in MakeGenericTypevoor meer informatie.

    Notitie

    Een geneste type dat wordt gedefinieerd door het verzenden van code in een dynamische assembly of met behulp van de Ilasm.exe (IL Assembler) is niet vereist om de typeparameters van de bijbehorende insluitingstypen op te nemen; Als deze echter niet zijn opgenomen, vallen de typeparameters niet binnen het bereik van de geneste klasse.

    Zie 'Geneste typen' in MakeGenericTypevoor meer informatie.

Ondersteuning voor klassenbibliotheek en taal

.NET biedt een aantal algemene verzamelingsklassen in de volgende naamruimten:

Algemene interfaces voor het implementeren van sorteer- en gelijkheidsvergelijkingen worden aangeboden in de System naamruimte, samen met algemene gedelegeerdentypen voor gebeurtenis-handlers, conversies en zoekpredicaten.

Ondersteuning voor generics is toegevoegd aan de naamruimte voor het System.Reflection onderzoeken van algemene typen en algemene methoden, voor System.Reflection.Emit het verzenden van dynamische assembly's die algemene typen en methoden bevatten, en voor System.CodeDom het genereren van brongrafieken die generics bevatten.

De algemene taalruntime biedt nieuwe opcodes en voorvoegsels ter ondersteuning van algemene typen in microsoft tussenliggende taal (MSIL), waaronder Stelem, Unbox_AnyLdelem, , Constraineden Readonly.

Visual C++, C# en Visual Basic bieden allemaal volledige ondersteuning voor het definiëren en gebruiken van generics. Zie Algemene typen in Visual Basic, Introduction to Generics en Overview of Generics in Visual C++voor meer informatie over taalondersteuning.

Geneste typen en generics

Een type dat is genest in een algemeen type kan afhankelijk zijn van de typeparameters van het algemene type insluiten. De algemene taalruntime beschouwt geneste typen als algemeen, zelfs als ze geen algemene typeparameters hebben. Wanneer u een exemplaar van een geneste type maakt, moet u typeargumenten opgeven voor alle algemene typen.

Titel Beschrijving
Algemene verzamelingen in .NET Hierin worden algemene verzamelingsklassen en andere algemene typen in .NET beschreven.
Algemene gemachtigden voor het bewerken van matrices en lijsten Beschrijft algemene gemachtigden voor conversies, zoekpredicaten en acties die moeten worden uitgevoerd op elementen van een matrix of verzameling.
Algemene interfaces Hierin worden algemene interfaces beschreven die algemene functionaliteit bieden in verschillende families van algemene typen.
Covariantie en Contravariantie Beschrijft covariantie en contravariantie in algemene typeparameters.
Veelgebruikte verzamelingstypen Biedt overzichtsinformatie over de kenmerken en gebruiksscenario's van de verzamelingstypen in .NET, inclusief algemene typen.
Wanneer algemene verzamelingen gebruiken Beschrijft algemene regels voor het bepalen wanneer algemene verzamelingstypen moeten worden gebruikt.
Procedure: Een algemeen type definiëren met reflectie-emit Hierin wordt uitgelegd hoe u dynamische assembly's genereert die algemene typen en methoden bevatten.
Algemene typen in Visual Basic Beschrijft de algemene functie voor Visual Basic gebruikers, waaronder instructies voor het gebruik en definiëren van algemene typen.
Inleiding tot Generics Biedt een overzicht van het definiëren en gebruiken van algemene typen voor C#-gebruikers.
Overzicht van generics in Visual C++ Beschrijft de algemene functie voor C++-gebruikers, inclusief de verschillen tussen generics en sjablonen.

Verwijzing

System.Collections.Generic

System.Collections.ObjectModel

System.Reflection.Emit.OpCodes