Résolution des méthodes d’extension
Comprenez comment le compilateur trouve les extensions.
Résolution des méthodes d’extension est une leçon C# Academy gratuite sur CoddyKit. Ceci est la leçon 3 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.
Comment le compilateur trouve les extensions
Lorsque vous écrivez value.Method() et qu’aucune méthode d’instance ne correspond, le compilateur recherche une méthode d’extension. Toutefois, il ne prend en compte que les extensions dont l’espace de noms contenant est accessible au moyen d’une directive using.
Les directives using rendent les extensions accessibles
Une extension n’est visible que si vous importez son espace de noms. Sans le bon using, la méthode semble ne pas exister, même si elle est compilée dans l’assemblage.
using System;
using MyHelpers; // brings StringExtensions into scope
namespace MyHelpers
{
public static class StringExtensions
{
public static string Reverse(this string s)
{
var arr = s.ToCharArray();
Array.Reverse(arr);
return new string(arr);
}
}
}
public class Program
{
public static void Main()
{
Console.WriteLine("hello".Reverse());
}
}Les méthodes d’instance sont vérifiées en premier
Le compilateur résout l’appel par étapes : il recherche d’abord une méthode d’instance correspondante, y compris parmi celles héritées. Ce n’est que si aucune ne convient qu’il recherche des méthodes d’extension.
using System;
using System.Collections.Generic;
public static class ListExt
{
// Ignored: List<int> already has Add(int)
public static void Add(this List<int> list, int a, int b)
=> list.Add(a + b);
}
public class Program
{
public static void Main()
{
var list = new List<int>();
list.Add(5); // the built-in instance Add wins for this signature
Console.WriteLine(list[0]);
}
}Les espaces de noms les plus proches sont prioritaires
Si deux extensions correspondent, celle dont l’espace de noms est le plus proche dans la hiérarchie d’imbrication est retenue. Une ambiguïté que le compilateur ne peut pas résoudre provoque une erreur de compilation et vous oblige à lever l’ambiguïté.
using System;
namespace Outer
{
public static class A { public static string Tag(this int n) => "A" + n; }
namespace Inner
{
public static class B { public static string Tag(this int n) => "B" + n; }
public class Program
{
public static void Main()
{
// B is in the nearer (Inner) namespace, so it is preferred
Console.WriteLine(7.Tag());
}
}
}
}Lever l’ambiguïté avec un appel statique
Lorsque des extensions entrent en conflit ou que vous souhaitez être explicite, appelez directement la méthode statique en utilisant le nom complet de sa classe. Cela contourne entièrement la résolution des extensions.
using System;
public static class FormatExt
{
public static string Bracket(this string s) => "[" + s + "]";
}
public class Program
{
public static void Main()
{
// Explicit static call, no ambiguity possible
Console.WriteLine(FormatExt.Bracket("x"));
}
}Résolution de surcharge entre les extensions
Si plusieurs méthodes d’extension portent le même nom, la résolution normale des surcharges choisit la meilleure correspondance selon les types de paramètres, comme pour une surcharge de méthode ordinaire.
using System;
public static class PrintExt
{
public static string Describe(this int n) => "int:" + n;
public static string Describe(this string s) => "str:" + s;
}
public class Program
{
public static void Main()
{
Console.WriteLine(42.Describe());
Console.WriteLine("hi".Describe());
}
}Inférence générique lors de la résolution
Pour les extensions génériques, le compilateur déduit les arguments de type à partir du receveur et des arguments. Si l’inférence échoue, l’extension n’est pas prise en compte.
using System;
using System.Collections.Generic;
public static class SeqExt
{
public static T FirstItem<T>(this IEnumerable<T> source)
{
foreach (var item in source) return item;
throw new InvalidOperationException("empty");
}
}
public class Program
{
public static void Main()
{
var nums = new List<int> { 5, 6, 7 };
// T inferred as int from the List<int> receiver
Console.WriteLine(nums.FirstItem());
}
}Directives globales using et importations implicites
Le C# moderne peut déclarer des directives global using afin qu’un espace de noms soit accessible dans tout le projet. Les bibliothèques d’extensions partagées deviennent ainsi disponibles partout sans répéter les importations.
using System;
// In a real project a separate file might say: global using MyHelpers;
namespace MyHelpers
{
public static class IntExt { public static int Twice(this int n) => n * 2; }
}
public class Program
{
public static void Main()
{
// Works here because MyHelpers is referenced explicitly
Console.WriteLine(MyHelpers.IntExt.Twice(8));
}
}Quand le type du receveur compte
La résolution dépend du type statique du receveur, et non de son type d’exécution. Une extension déclarée pour un type de base s’applique même lorsque la variable contient une instance dérivée, sauf si une extension plus spécifique est accessible.
using System;
public class Animal { }
public class Cat : Animal { }
public static class AnimalExt
{
public static string Kind(this Animal a) => "animal";
}
public class Program
{
public static void Main()
{
Animal a = new Cat();
// Chosen by static type Animal
Console.WriteLine(a.Kind());
}
}Un modèle mental pour la résolution
Considérez l’ordre suivant : (1) les méthodes d’instance, puis (2) les méthodes d’extension provenant des espaces de noms importés, en commençant par les plus proches, puis (3) la résolution des surcharges parmi les candidates. Connaître cet ordre explique presque tous les résultats surprenants.
using System;
public static class Ext
{
public static string Wrap(this string s) => "<" + s + ">";
}
public class Program
{
public static void Main()
{
// No instance Wrap exists, so the extension is used
Console.WriteLine("node".Wrap());
}
}Essayez par vous-même
Définissez une extension dans un espace de noms, importez-la et appelez-la. Appelez ensuite la même méthode explicitement comme méthode statique pour constater que les deux approches fonctionnent.
using System;
using Text.Helpers;
namespace Text.Helpers
{
public static class StringExtensions
{
public static int Vowels(this string s)
{
int count = 0;
foreach (var c in s.ToLower())
if ("aeiou".IndexOf(c) >= 0) count++;
return count;
}
}
}
public class Program
{
public static void Main()
{
Console.WriteLine("education".Vowels());
Console.WriteLine(Text.Helpers.StringExtensions.Vowels("education"));
}
}Vérification rapide
Réfléchissez à ce qui rend une méthode d’extension visible.
Récapitulatif
La résolution des méthodes d’extension suit un ordre précis.
- Les méthodes d’instance sont essayées en premier ; les extensions ne comblent que les lacunes.
- Une extension n’est visible que si son espace de noms est accessible via
usingouglobal using. - Les espaces de noms les plus proches sont prioritaires ; les égalités non résolues provoquent des erreurs de compilation.
- Vous pouvez toujours appeler explicitement la méthode statique pour lever l’ambiguïté.
- La résolution utilise le type statique du receveur.
Questions Fréquemment Posées
La leçon « Résolution des méthodes d’extension » est-elle gratuite ?
Oui — le texte complet de « Résolution des méthodes d’extension » 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 « Résolution des méthodes d’extension » ?
Comprenez comment le compilateur trouve les extensions. 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 3 sur 4.
Combien de temps prend la leçon « Résolution des méthodes d’extension » ?
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