Pourquoi GetType () ne peut-il pas trouver des types lorsqu’il est appelé via un délégué de groupe de méthodes?

Nous avons un programme très simple invoquant la méthode statique Type.GetType . Les deux exemples doivent renvoyer une instance de type valide. Seul le deuxième est réellement. Il semble que quelque chose de bizarre se passe avec l’parsing de stack utilisée par GetType , mais quel est le problème ici? Est-ce un bug ou une fonctionnalité obscure?

 public class TestClass { } class Program { static void Main(ssortingng[] args) { var fullName = typeof(TestClass).FullName; Console.WriteLine("Full name: {0}", fullName); new[] { fullName }.Select(Type.GetType).ToList().ForEach(t => Console.WriteLine("Method group: '{0}'", t)); new[] { fullName }.Select(t => Type.GetType(t)).ToList().ForEach(t => Console.WriteLine("Closure: '{0}'", t)); } } 

Fonctionnement:

 Full name: GetTypeBeingWeird.TestClass Method group: '' Closure: 'GetTypeBeingWeird.TestClass' 

C’est vraiment intéressant. C’est un mélange du comportement de Type.GetType(ssortingng) en termes d’assembly appelant et du fonctionnement des conversions de groupes de méthodes.

Tout d’abord, la documentation Type.GetType comprend ceci:

Si typeName inclut l’espace de noms mais pas le nom de l’assembly, cette méthode recherche uniquement l’assembly de l’object appelant et Mscorlib.dll, dans cet ordre.

Lors de votre premier appel, vous transmettez un délégué qui appelle Type.GetType … mais il n’est pas particulièrement appelé par votre assembly. Il est effectivement appelé directement à partir de la méthode Select dans LINQ … Si vous avez regardé la trace de la stack depuis Type.GetType , vous verriez Select tant Type.GetType direct, je crois.

Dans votre deuxième appel, vous transmettez une fermeture qui appelle Type.GetType , et cet appel se trouve dans votre assembly.

C’est pourquoi il trouve le type dans le second cas mais pas le premier. Ceci est encore validé en spécifiant un type qui se trouve dans l’assembly LINQ:

 var fullName = typeof(Enumerable).FullName; 

Ensuite, les résultats sont inverses:

 Full name: System.Linq.Enumerable Method group: 'System.Linq.Enumerable' Closure: '' 

Si vous spécifiez quelque chose dans mscorlib (par exemple, typeof(ssortingng).FullName ), les deux approches fonctionnent:

 Full name: System.Ssortingng Method group: 'System.Ssortingng' Closure: 'System.Ssortingng' 

Pour contourner cette bizarrerie lorsque vous recherchez votre classe, toujours en utilisant un groupe de méthodes, il vous suffit de fournir le nom qualifié d’assembly à la place:

 var fullName = typeof(TestClass).AssemblyQualifiedName;