Delen via


Overzicht van algemene typen

Ontwikkelaars gebruiken altijd generics in .NET, impliciet of expliciet. Wanneer u LINQ in .NET gebruikt, hebt u ooit gemerkt dat u ermee IEnumerable<T>werkt? Of als u ooit een onlinevoorbeeld van een 'algemene opslagplaats' hebt gezien voor het praten met databases met Behulp van Entity Framework, hebt u gezien dat de meeste methoden worden geretourneerd IQueryable<T>? Misschien hebt u zich afgevraagd wat de T in deze voorbeelden is en waarom het daar is.

Voor het eerst geïntroduceerd in .NET Framework 2.0, zijn generieken in feite een 'codesjabloon' waarmee ontwikkelaars typeveilige gegevensstructuren kunnen definiëren zonder dat ze zich aan een daadwerkelijk gegevenstype hoeven te binden. Is bijvoorbeeld List<T> een algemene verzameling die kan worden gedeclareerd en gebruikt met elk type, zoals List<int>, List<string>of List<Person>.

Laten we eens kijken naar een specifieke klas voor en na het toevoegen van generics om te begrijpen waarom generics nuttig zijn: ArrayList In .NET Framework 1.0 waren de elementen van het ArrayList type Object. Elk element dat aan de verzameling is toegevoegd, is op de achtergrond geconverteerd naar een Object. Hetzelfde gebeurt wanneer u elementen uit de lijst leest. Dit proces staat bekend als boksen en uitpakken en heeft invloed op de prestaties. Afgezien van de prestaties is er echter geen manier om het type gegevens in de lijst tijdens het compileren te bepalen, wat voor een kwetsbare code zorgt. Generieken lossen dit probleem op door het type gegevens te definiëren dat elk exemplaar van de lijst bevat. U kunt bijvoorbeeld alleen gehele getallen toevoegen aan List<int> en alleen personen toevoegen aan List<Person>.

Generics zijn ook beschikbaar tijdens runtime. De runtime weet welk type gegevensstructuur u gebruikt en kan deze efficiënter opslaan in het geheugen.

Het volgende voorbeeld is een klein programma dat de efficiëntie illustreert van het gegevensstructuurtype tijdens runtime:

  using System;
  using System.Collections;
  using System.Collections.Generic;
  using System.Diagnostics;

  namespace GenericsExample {
    class Program {
      static void Main(string[] args) {
        //generic list
        List<int> ListGeneric = new List<int> { 5, 9, 1, 4 };
        //non-generic list
        ArrayList ListNonGeneric = new ArrayList { 5, 9, 1, 4 };
        // timer for generic list sort
        Stopwatch s = Stopwatch.StartNew();
        ListGeneric.Sort();
        s.Stop();
        Console.WriteLine($"Generic Sort: {ListGeneric}  \n Time taken: {s.Elapsed.TotalMilliseconds}ms");

        //timer for non-generic list sort
        Stopwatch s2 = Stopwatch.StartNew();
        ListNonGeneric.Sort();
        s2.Stop();
        Console.WriteLine($"Non-Generic Sort: {ListNonGeneric}  \n Time taken: {s2.Elapsed.TotalMilliseconds}ms");
        Console.ReadLine();
      }
    }
  }

Dit programma produceert uitvoer die vergelijkbaar is met de volgende:

Generic Sort: System.Collections.Generic.List`1[System.Int32]
 Time taken: 0.0034ms
Non-Generic Sort: System.Collections.ArrayList
 Time taken: 0.2592ms

Het eerste wat u hier kunt zien, is dat het sorteren van de algemene lijst aanzienlijk sneller is dan het sorteren van de niet-algemene lijst. Mogelijk ziet u ook dat het type voor de algemene lijst uniek is ([System.Int32]), terwijl het type voor de niet-algemene lijst wordt gegeneraliseerd. Omdat de runtime weet dat het algemeen List<int> van het type Int32is, kunnen de lijstelementen worden opgeslagen in een onderliggende matrix met gehele getallen in het geheugen, terwijl het niet-algemene ArrayList element elke lijstelement naar een object moet casten. Zoals in dit voorbeeld wordt weergegeven, nemen de extra casts tijd in beslag en vertraagt u het sorteren van de lijst.

Een extra voordeel van de runtime die weet wat het type van uw algemene is, is een betere foutopsporingservaring. Wanneer u een algemene foutopsporing uitvoert in C#, weet u welk type elk element zich in uw gegevensstructuur bevindt. Zonder generics zou u geen idee hebben welk type elk element was.

Zie ook