C# Generics Uitgelegd: Flexibele, Type-Veilige Code voor Elk Datatype
Wat zijn Generics?
Generics stellen je in staat om de specificatie van het datatype van programmeerelementen in een klasse of methode te definiëren tot het moment dat deze daadwerkelijk in het programma worden gebruikt. Met andere woorden: generics laten je een klasse of methode schrijven die met elk datatype kan werken.
Je schrijft de specificaties voor de klasse of methode, met vervangende parameters voor datatypen. Wanneer de compiler een constructor voor de klasse of een functieaanroep voor de methode tegenkomt, genereert hij code om het specifieke datatype te verwerken. Een eenvoudig voorbeeld verheldert het concept:
using System;
using System.Collections.Generic;
namespace GenericApplication {
public class MyGenericArray<T> {
private T[] array;
public MyGenericArray(int size) {
array = new T[size + 1];
}
public T getItem(int index) {
return array[index];
}
public void setItem(int index, T value) {
array[index] = value;
}
}
class Tester {
static void Main(string[] args) {
// Een int array declareren
MyGenericArray<int> intArray = new MyGenericArray<int>(5);
// Waarden instellen
for (int c = 0; c < 5; c++) {
intArray.setItem(c, c * 5);
}
// Waarden ophalen
for (int c = 0; c < 5; c++) {
Console.Write(intArray.getItem(c) + " ");
}
Console.WriteLine();
// Een character array declareren
MyGenericArray<char> charArray = new MyGenericArray<char>(5);
// Waarden instellen
for (int c = 0; c < 5; c++) {
charArray.setItem(c, (char)(c + 97));
}
// Waarden ophalen
for (int c = 0; c < 5; c++) {
Console.Write(charArray.getItem(c) + " ");
}
Console.WriteLine();
Console.ReadKey();
}
}
}
Wanneer de bovenstaande code wordt gecompileerd en uitgevoerd, produceert dit het volgende resultaat:
0 5 10 15 20 a b c d e
Kenmerken van Generics
Generics verrijken je programma's op de volgende manieren:
Het helpt om herbruikbaarheid van code, typeveiligheid en prestaties te maximaliseren.
Je kunt generische verzamelingsklassen maken. De .NET Framework class library bevat diverse nieuwe generische verzamelingsklassen in de System.Collections.Generic namespace. Je kunt deze gebruiken in plaats van de klassen in System.Collections.
Je kunt je eigen generische interfaces, klassen, methoden, events en delegates maken.
Je kunt generieke klassen beperken (constrained) om toegang te krijgen tot methoden op specifieke datatypen.
Je kunt informatie verkrijgen over de typen die in een generiek datatype worden gebruikt tijdens runtime via reflectie.
Generische Methodes
In het vorige voorbeeld hebben we een generieke klasse gebruikt; we kunnen ook een generieke methode declareren met een typeparameter. Het volgende programma illustreert het concept:
using System;
using System.Collections.Generic;
namespace GenericMethodAppl {
class Program {
static void Swap<T>(ref T lhs, ref T rhs) {
T temp;
temp = lhs;
lhs = rhs;
rhs = temp;
}
static void Main(string[] args) {
int a, b;
char c, d;
a = 10; b = 20;
c = 'I'; d = 'V';
// Waarden voor swap tonen
Console.WriteLine("Int waarden voor swap:");
Console.WriteLine("a = {0}, b = {1}", a, b);
Console.WriteLine("Char waarden voor swap:");
Console.WriteLine("c = {0}, d = {1}", c, d);
// Swap aanroepen
Swap<int>(ref a, ref b);
Swap<char>(ref c, ref d);
// Waarden na swap tonen
Console.WriteLine("Int waarden na swap:");
Console.WriteLine("a = {0}, b = {1}", a, b);
Console.WriteLine("Char waarden na swap:");
Console.WriteLine("c = {0}, d = {1}", c, d);
Console.ReadKey();
}
}
}
Wanneer de bovenstaande code wordt gecompileerd en uitgevoerd, produceert dit het volgende resultaat:
Int waarden voor swap: a = 10, b = 20 Char waarden voor swap: c = I, d = V Int waarden na swap: a = 20, b = 10 Char waarden na swap: c = V, d = I
Generische Delegates
Je kunt een generieke delegate definiëren met typeparameters. Bijvoorbeeld:
delegate T NumberChanger<T>(T n);
Het volgende voorbeeld toont het gebruik van deze delegate:
using System;
using System.Collections.Generic;
delegate T NumberChanger<T>(T n);
namespace GenericDelegateAppl {
class TestDelegate {
static int num = 10;
public static int AddNum(int p) { num += p; return num; }
public static int MultNum(int q) { num *= q; return num; }
public static int getNum() { return num; }
static void Main(string[] args) {
// Delegate instanties aanmaken
NumberChanger<int> nc1 = new NumberChanger<int>(AddNum);
NumberChanger<int> nc2 = new NumberChanger<int>(MultNum);
// Methodes aanroepen via de delegate objecten
nc1(25);
Console.WriteLine("Waarde van Num: {0}", getNum());
nc2(5);
Console.WriteLine("Waarde van Num: {0}", getNum());
Console.ReadKey();
}
}
}
Wanneer de bovenstaande code wordt gecompileerd en uitgevoerd, produceert dit het volgende resultaat:
Waarde van Num: 35 Waarde van Num: 175
C Taal
- C# Hello World – Uw eerste C# applicatie bouwen
- C# Keywords en Identifiers begrijpen: Regels, lijsten en best practices
- C# Variabelen & Primitive Datatypes onder de knie krijgen: Complete gids
- C# Operators – Uitgebreide gids voor operators in C#
- C# Bitwise en Bit Shift Operators: Een Uitgebreide Gids
- C# Fundamentals: Invoer en Uitvoer Basis
- C# Expressies, Statements & Blokken: Uitgebreide Gids met Praktische Voorbeelden
- C# Comments Onder de Loep: Types, Best Practices en XML Documentatie
- De C# Switch Statement: Syntaxis, Voorbeelden & Best Practices
- De C# Ternaire Operator: Beknopte Gids voor Conditionele Expressies
- C# Break Statement: Hoe en Wanneer Te Gebruiken