6Generics
Een typeparameter T maakt een klasse of methode herbruikbaar voor elk type, met behoud van type-veiligheid. Je kent ze al: List<T>, Dictionary<K,V>.
// Generieke klasse (UML: Doos met T in stippelvakje) public class Doos<T> { public T Inhoud { get; set; } public Doos(T inhoud) { Inhoud = inhoud; } public void Toon() => Console.WriteLine($"De doos bevat: {Inhoud}"); } var d1 = new Doos<string>("Boek"); var d2 = new Doos<int>(42); // Generieke methode public static void ToonWaarde<T>(T waarde) => Console.WriteLine($"Waarde: {waarde}"); Helper.ToonWaarde(42); // T wordt int (afgeleid) // Met constraint public static T Grootste<T>(T a, T b) where T : IComparable<T> => a.CompareTo(b) > 0 ? a : b;
Uitleg
Een generieke klasse of methode werkt met een typeparameter T die je pas bij gebruik invult. Zo schrijf je één Doos voor strings, getallen of objecten, en blijft alles type-veilig. Met where eis je iets van T, zoals dat hij vergelijkbaar is.
CompareTo- Geeft negatief (eerder), 0 (gelijk) of positief (later) terug.
IComparable<T>- .NET-interface die zegt dat objecten onderling vergelijkbaar zijn.
where T :- Constraint: legt vast wat het type
Tminimaal moet kunnen of zijn. <T>- Typeparameter: wordt pas bij gebruik ingevuld, bijvoorbeeld
Doos<string>. static- Hoort bij de klasse zelf, niet bij één object; gedeeld door alle objecten.
=>- Korte schrijfwijze voor een methode of property die één expressie teruggeeft; in LINQ ook de pijl van een lambda.
$"...{x}"- String-interpolatie: zet de waarde van
xdirect in de tekst. var- De compiler leidt het type zelf af uit de rechterkant.
// Generiek logboek public class Logboek<T> where T : LogItem { private readonly List<T> _items = new(); public void Voeg(T item) => _items.Add(item); public IReadOnlyList<T> FilterOpErnst(Ernst e) => _items.Where(i => i.Ernst == e).ToList(); public IReadOnlyList<T> Chronologisch() => _items.OrderBy(i => i.Tijdstip).ToList(); }
Uitleg
Een generiek logboek dat alleen LogItems (of subklassen) accepteert, dankzij de constraint. Daardoor weet de compiler dat elk item een Ernst en Tijdstip heeft en kun je daarop filteren en sorteren met LINQ.
IReadOnlyList<T>- Alleen-lezen weergave van een lijst: wel lezen en doorlopen, niet toevoegen of verwijderen.
Where- LINQ: houdt alleen de elementen over die aan de voorwaarde voldoen.
OrderBy- LINQ: sorteert op de opgegeven eigenschap (oplopend).
ToList()- Maakt van het LINQ-resultaat een nieuwe
List<T>. where T :- Constraint: legt vast wat het type
Tminimaal moet kunnen of zijn. <T>- Typeparameter: wordt pas bij gebruik ingevuld, bijvoorbeeld
Doos<string>. private- Alleen zichtbaar binnen deze klasse.
readonly- Veld mag alleen bij de declaratie of in de constructor een waarde krijgen.
=>- Korte schrijfwijze voor een methode of property die één expressie teruggeeft; in LINQ ook de pijl van een lambda.
new()- Target-typed new: het type wordt afgeleid uit de declaratie links.
List<T>- Lijst die automatisch groeit; toevoegen met
Add, aantal metCount.
| Constraint | T moet ... |
|---|---|
where T : class | een referentietype zijn |
where T : struct | een waardetype zijn |
where T : new() | een lege constructor hebben |
where T : Voertuig | (sub)klasse van Voertuig zijn |
where T : IComparable<T> | die interface implementeren |
ref: zonder ref krijgt een methode een kopie van een waardetype. void Verdubbel(ref int g) { g *= 2; } aanroepen met Verdubbel(ref x) wijzigt x zelf. out: methode moet de waarde vullen (zoals int.TryParse).