Pourquoi le code ci-dessous fait-il planter le compilateur .NET ? Il a été testé sur csc.exe version 4.0.
Voir par exemple ici pour une démo en ligne sur une version différente - elle se bloque de la même manière alors qu'il est indiqué que la dynamique n'est pas prise en charge. https://dotnetfiddle.net/FMn59S :
Erreur de compilation (ligne 0, col 0) : Internal Compiler Error (0xc0000005 at address xy) : le coupable probable est 'TRANSFORM'.
La méthode d'extension fonctionne bien sur List<dynamic>
cependant.
using System;
using System.Collections.Generic;
static class F {
public static void M<T>(this IEnumerable<T> enumeration, Action<T> action){}
static void U(C.K d) {
d.M(kvp => Console.WriteLine(kvp));
}
}
class C {
public class K : Dictionary<string, dynamic>{}
}
Mise à jour : cela ne fait pas planter le compilateur
static void U(Dictionary<string, dynamic> d)
{
d.M(kvp => Console.WriteLine(kvp));
}
Mise à jour 2 : le même bogue a été signalé dans http://connect.microsoft.com/VisualStudio/feedback/details/892372/compiler-error-with-dynamic-dictinoaries . Le bogue a été signalé pour FirstOrDefault, mais il semble que le compilateur se plante sur toute méthode d'extension appliquée à une classe dérivée de Dictionary<T1,T2>, où au moins un des types de paramètres est dynamic
. Voir ci-dessous une description encore plus générale du problème par Erik Funkenbusch.
Mise à jour 3 : un autre comportement non standard. Lorsque j'essaie d'appeler une méthode d'extension comme une méthode statique, c'est-à-dire, F.M(d, kvp => Console.WriteLine(kvp));
le compilateur ne se plante pas, mais il ne trouve pas la surcharge : Argument 1: cannot convert from 'C.K' to 'System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<string,dynamic>>'
Mise à jour 4 - SOLUTION (en quelque sorte) : Hans a esquissé une 2ème solution de contournement, qui est sémantiquement équivalente au code original, mais ne fonctionne que pour l'appel de la méthode d'extension et non pour l'appel standard. Puisque le bogue est probablement causé par le fait que le compilateur n'arrive pas à caster une classe dérivée d'une classe générique avec plusieurs paramètres (dont l'un est dynamique) vers son supertype, la solution est de fournir un cast explicite. Voir https://dotnetfiddle.net/oNvlcL :
((Dictionary<string, dynamic>)d).M(kvp => Console.WriteLine(kvp));
M((Dictionary<string, dynamic>)d, kvp => Console.WriteLine(kvp));