types génériques en C# : ce sont des outils puissants et flexibles pour créer du code réutilisable, sécurisé et fortement typé.
🔷 C’est quoi un type générique ?
Un type générique est un modèle qui fonctionne avec n’importe quel type de données.
Tu le reconnais avec les chevrons <T>
.
Tu peux voir ça comme une boîte vide dans laquelle tu décides plus tard quel type tu mets.
✅ Exemple simple
public class Boite<T>
{
public T Contenu;
public void Afficher()
{
Console.WriteLine($"Contenu : {Contenu}");
}
}
Utilisation :
var boite1 = new Boite<int> { Contenu = 42 };
var boite2 = new Boite<string> { Contenu = "Hello" };
boite1.Afficher(); // Contenu : 42
boite2.Afficher(); // Contenu : Hello
🎯 Pourquoi utiliser des génériques ?
✅ Réutilisable : pas besoin d’écrire 10 fois le même code pour différents types.
✅ Typage fort : évite les erreurs à l’exécution (contrairement à object
).
✅ Performance : pas de boxing/unboxing inutile.
✅ Lisible et maintenable.
📚 Exemples dans le framework .NET
Tu utilises sûrement déjà des génériques sans t’en rendre compte :
Générique | Description |
---|---|
List<T> |
Liste de type T |
Dictionary<TKey, TValue> |
Dictionnaire clé/valeur |
Func<T, TResult> |
Représente une fonction |
Task<T> |
Représente un résultat asynchrone |
Nullable<T> |
Permet de rendre un type valeur nullable (int? = Nullable<int> ) |
🔒 Contraintes (optionnelles)
Tu peux restreindre les types utilisables avec des contraintes (where
clause).
Exemple :
public class Fabrique<T> where T : new()
{
public T Creer()
{
return new T(); // Nécessite un constructeur sans paramètre
}
}
Autres contraintes possibles :
-
where T : class
→ seulement des types référence -
where T : struct
→ seulement des types valeur -
where T : BaseClass
→ T doit hériter deBaseClass
-
where T : interface
→ T doit implémenter une interface
🧠 Résumé
Élément | Exemple | Description |
---|---|---|
Classe générique | class MaClasse<T> |
Classe pour tout type |
Méthode générique | void Afficher<T>(T x) |
Fonction générique |
Contrainte | where T : class |
Restreindre les types autorisés |
1. **Contrainte de type (Type Constraint)** :
- `where T : class`: Indique que `T` doit être une référence de classe (type référence).
- `where T : struct`: Indique que `T` doit être une structure (type valeur).
- `where T : new()`: Indique que `T` doit avoir un constructeur public sans paramètre (constructeur par défaut).
- `where T : nomInterface`: Indique que `T` doit implémenter l'interface spécifiée.
2. **Contrainte de base (Base Constraint)** :
- `where T : Base`: Indique que `T` doit être ou dériver de la classe `Base`.
3. **Contrainte de conversion (Conversion Constraint)** :
- `where T : U`: Indique que `T` doit pouvoir être converti implicitement en `U`.
4. **Contrainte de type nullable (Nullable Type Constraint)** :
- `where T : struct, Nullable`: Indique que `T` doit être une structure nullable.
5. **Contrainte de délégué (Delegate Constraint)** :
- `where T : delegate`: Indique que `T` doit être un type de délégué.
6. **Contrainte de paramètre de type (Type Parameter Constraint)** :
- `where T : args`: Indique que `T` doit être un tableau (array).
Aucun commentaire:
Enregistrer un commentaire