Étendre les interfaces et les génériques
Ajoutez un comportement à de nombreux types à la fois.
Étendre les interfaces et les génériques est une leçon C# Academy gratuite sur CoddyKit. Ceci est la leçon 2 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage C# Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours C# Academy comprend 4 leçons au total.
Étendre des interfaces
Vous pouvez écrire une méthode d’extension dont le paramètre this est une interface. Tout type qui implémente cette interface obtient instantanément cette méthode. C’est exactement ainsi que LINQ ajoute des dizaines de méthodes à IEnumerable<T>.
Une extension générique sur IEnumerable
En rendant la méthode générique sur T et en étendant IEnumerable<T>, la fonction auxiliaire fonctionne avec toute séquence : listes, tableaux, résultats de requêtes, et bien plus.
using System;
using System.Collections.Generic;
public static class EnumerableExtensions
{
public static bool IsEmpty<T>(this IEnumerable<T> source)
{
foreach (var item in source) return false;
return true;
}
}
public class Program
{
public static void Main()
{
var nums = new List<int> { 1, 2, 3 };
Console.WriteLine(nums.IsEmpty());
Console.WriteLine(new int[0].IsEmpty());
}
}Parcourir la séquence
Dans l’extension, vous traitez le paramètre comme n’importe quel IEnumerable<T>. Ici, nous calculons une somme sans dépendre de LINQ.
using System;
using System.Collections.Generic;
public static class EnumerableExtensions
{
public static int SumValues(this IEnumerable<int> source)
{
int total = 0;
foreach (var n in source) total += n;
return total;
}
}
public class Program
{
public static void Main()
{
var nums = new List<int> { 10, 20, 30 };
Console.WriteLine(nums.SumValues());
}
}Renvoyer une nouvelle séquence
Les extensions peuvent également renvoyer des séquences. Associées à yield return, elles deviennent des opérateurs différés de style LINQ.
using System;
using System.Collections.Generic;
public static class EnumerableExtensions
{
public static IEnumerable<T> EveryOther<T>(this IEnumerable<T> source)
{
bool take = true;
foreach (var item in source)
{
if (take) yield return item;
take = !take;
}
}
}
public class Program
{
public static void Main()
{
var letters = new List<string> { "a", "b", "c", "d", "e" };
foreach (var l in letters.EveryOther())
Console.WriteLine(l);
}
}Contraintes de types génériques
Vous pouvez contraindre le paramètre générique afin d’exiger certaines fonctionnalités. Ici, where T : IComparable<T> nous permet de comparer les éléments pour trouver un maximum.
using System;
using System.Collections.Generic;
public static class EnumerableExtensions
{
public static T MaxItem<T>(this IEnumerable<T> source) where T : IComparable<T>
{
bool started = false;
T best = default;
foreach (var item in source)
{
if (!started || item.CompareTo(best) > 0) { best = item; started = true; }
}
return best;
}
}
public class Program
{
public static void Main()
{
var nums = new List<int> { 3, 9, 1, 7 };
Console.WriteLine(nums.MaxItem());
}
}Étendre une interface personnalisée
Vos propres interfaces en bénéficient également. Définissez une interface, puis ajoutez un comportement partagé au moyen d’extensions au lieu de le dupliquer dans chaque implémentation.
using System;
public interface INamed { string Name { get; } }
public class Dog : INamed { public string Name => "Rex"; }
public static class NamedExtensions
{
public static string Greeting(this INamed n) => "Hello, " + n.Name;
}
public class Program
{
public static void Main()
{
var d = new Dog();
Console.WriteLine(d.Greeting());
}
}Plusieurs paramètres de type
Les extensions peuvent être génériques sur plusieurs paramètres de type. Cet utilitaire de projection transforme une séquence au moyen d’une fonction, un peu comme Select de LINQ.
using System;
using System.Collections.Generic;
public static class EnumerableExtensions
{
public static IEnumerable<TResult> Map<TSource, TResult>(
this IEnumerable<TSource> source, Func<TSource, TResult> f)
{
foreach (var item in source) yield return f(item);
}
}
public class Program
{
public static void Main()
{
var nums = new List<int> { 1, 2, 3 };
foreach (var s in nums.Map(n => "#" + n))
Console.WriteLine(s);
}
}Combiner avec LINQ intégré
Vos méthodes d’extension coexistent avec LINQ. Vous pouvez enchaîner votre opérateur personnalisé avec des opérateurs standard dans une seule chaîne fluide.
using System;
using System.Collections.Generic;
using System.Linq;
public static class EnumerableExtensions
{
public static IEnumerable<T> EveryOther<T>(this IEnumerable<T> source)
{
bool take = true;
foreach (var item in source) { if (take) yield return item; take = !take; }
}
}
public class Program
{
public static void Main()
{
var nums = Enumerable.Range(1, 10);
var result = nums.Where(n => n > 2).EveryOther().ToList();
Console.WriteLine(string.Join(", ", result));
}
}Étendre IEnumerable couvre de nombreux types
Comme les tableaux, les listes, les dictionnaires, les ensembles de hachage et les résultats de requêtes implémentent tous IEnumerable<T>, une seule extension les couvre tous à la fois.
using System;
using System.Collections.Generic;
public static class EnumerableExtensions
{
public static int CountItems<T>(this IEnumerable<T> source)
{
int n = 0;
foreach (var item in source) n++;
return n;
}
}
public class Program
{
public static void Main()
{
Console.WriteLine(new[] { 1, 2, 3 }.CountItems());
Console.WriteLine(new HashSet<string> { "a", "b" }.CountItems());
}
}Pourquoi ce modèle passe à l’échelle
Les extensions d’interface vous offrent des utilitaires polymorphes sans héritage. Écrivez la logique une seule fois à partir de l’interface, et chaque implémentation, actuelle ou future, en bénéficie automatiquement.
using System;
using System.Collections.Generic;
public static class EnumerableExtensions
{
public static string JoinWith<T>(this IEnumerable<T> source, string sep)
{
return string.Join(sep, source);
}
}
public class Program
{
public static void Main()
{
var nums = new List<int> { 1, 2, 3 };
Console.WriteLine(nums.JoinWith(" -> "));
}
}Essayez par vous-même
Créez un petit opérateur générique sur IEnumerable<T> et enchaînez-le avec LINQ. Remarquez qu’il fonctionne avec n’importe quel type de séquence.
using System;
using System.Collections.Generic;
using System.Linq;
public static class EnumerableExtensions
{
public static IEnumerable<T> WithoutDuplicatesByKey<T, TKey>(
this IEnumerable<T> source, Func<T, TKey> keySelector)
{
var seen = new HashSet<TKey>();
foreach (var item in source)
if (seen.Add(keySelector(item))) yield return item;
}
}
public class Program
{
public static void Main()
{
var words = new[] { "apple", "avocado", "banana", "cherry", "blueberry" };
var firstPerLetter = words.WithoutDuplicatesByKey(w => w[0]);
Console.WriteLine(string.Join(", ", firstPerLetter));
}
}Vérification rapide
Réfléchissez à la manière dont les extensions de style LINQ sont déclarées.
Récapitulatif
Étendre des interfaces, en particulier IEnumerable<T>, constitue la base de la programmation de style LINQ.
- Rendez la méthode générique et utilisez l’interface comme type
this. - Utilisez
yield returnpour créer des opérateurs différés. - Appliquez des contraintes
wherepour exiger des fonctionnalités commeIComparable<T>. - Une seule extension d’interface couvre toutes les implémentations, y compris les futures.
Questions Fréquemment Posées
La leçon « Étendre les interfaces et les génériques » est-elle gratuite ?
Oui — le texte complet de « Étendre les interfaces et les génériques » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours C# Academy, passe à CoddyKit PRO. Le cours C# Academy comprend 4 leçons au total.
Qu'est-ce que j'apprendrai dans « Étendre les interfaces et les génériques » ?
Ajoutez un comportement à de nombreux types à la fois. Tu pratiques C# Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.
Dois-je avoir de l'expérience pour commencer C# Academy ?
Aucune expérience préalable n'est requise. C# Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 2 sur 4.
Combien de temps prend la leçon « Étendre les interfaces et les génériques » ?
La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.
Peux-tu écrire et exécuter du code dans cette leçon C# Academy ?
Oui. Chaque leçon C# Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.
Toutes les leçons de ce cours
- Définir des méthodes d’extension
- Étendre les interfaces et les génériques
- Résolution des méthodes d’extension
- Concevoir de bonnes extensions