Test(A);
Cela échoue car la seule méthode applicable ( Test<T>(Action<T>)
) nécessite une inférence de type, et l'algorithme d'inférence de type exige que chaque argument soit d'un certain type ou soit une fonction anonyme. (Ce fait est déduit de la spécification de l'algorithme d'inférence de type (§7.5.2)) La méthode groupe A
n'est pas d'un type quelconque (même si elle peut être convertie en un type de délégué approprié), et ce n'est pas une fonction anonyme.
Test<string>(A);
Cette opération réussit, la différence étant que l'inférence de type n'est pas nécessaire pour lier Test, et que le groupe de méthodes A peut être converti dans le type de paramètre de délégué requis. void Action<string>(string)
.
Test((string a) => {});
Cela réussit, la différence étant que l'algorithme d'inférence de type prend en compte les fonctions anonymes dans la première phase (§7.5.2.1). Les types de paramètre et de retour de la fonction anonyme sont connus, de sorte qu'une inférence de type de paramètre explicite peut être faite, et une correspondance est ainsi établie entre les types dans la fonction anonyme ( void ?(string)
) et le paramètre de type dans le type de délégué de l'objet Test
le paramètre de la méthode ( void Action<T>(T)
). Aucun algorithme n'est spécifié pour les groupes de méthodes qui correspondrait à cet algorithme pour les fonctions anonymes.
Test((Action<string>)A);
Cette opération réussit, la différence étant que le paramètre de groupe de méthodes non typé A
est converti en un type, permettant ainsi l'inférence de type de Test
pour procéder normalement avec une expression d'un type particulier comme seul argument de la méthode.
Je ne vois pas pourquoi, en théorie, la résolution des surcharges ne pourrait pas être tentée sur le groupe de méthodes. A
. Ensuite, si une seule meilleure liaison est trouvée, le groupe de méthodes pourrait recevoir le même traitement qu'une fonction anonyme. Ceci est particulièrement vrai dans des cas comme celui-ci où le groupe de méthodes contient exactement un candidat et n'a pas de paramètres de type. Mais la raison pour laquelle cela ne fonctionne pas dans C#4 semble être le fait que cette fonctionnalité n'a pas été conçue et implémentée. Compte tenu de la complexité de cette fonctionnalité, de la rareté de son application et de l'existence de trois solutions de contournement faciles, je ne vais pas retenir mon souffle pour elle !