Essayez de compiler le code suivant et vous constaterez que le compilateur prend> 3 Go de RAM (toute la mémoire libre sur ma machine) et très longtemps pour compiler (en fait, j'obtiens une exception IO après 10 minutes).
using System;
using System.Linq;
public class Test
{
public static void Main()
{
Enumerable.Range(0, 1).Sum(a =>
Enumerable.Range(0, 1).Sum(b =>
Enumerable.Range(0, 1).Sum(c =>
Enumerable.Range(0, 1).Sum(d =>
Enumerable.Range(0, 1).Sum(e =>
Enumerable.Range(0, 1).Sum(f =>
Enumerable.Range(0, 1).Count(g => true)))))));
}
}
Quelqu'un peut-il expliquer ce comportement curieux?
Version CS: compilateur Microsoft (R) Visual C # version 4.0.30319.17929 Nom du système d'exploitation: Microsoft Windows 7 Ultimate Version du système d'exploitation: 6.1.7601 Service Pack 1 Build 7601
Réponses:
Je crois que cela est lié à l'inférence de type et / ou à la génération lambda (lorsque l'inférence de type doit aller dans la direction opposée à la normale), combinée à la résolution de surcharge. Malheureusement, le simple fait de fournir les paramètres de type n'aide pas la situation (où il doit probablement encore effectuer la vérification de type).
Le code suivant, qui devrait logiquement être le code équivalent du vôtre, une fois que les lambdas ont été analysés, se compile sans problème:
Je crois qu'Eric Lippert a déjà posté que l'inférence de type est l'un des endroits du compilateur C # où (certains problèmes) peuvent forcer le compilateur à essayer de résoudre un problème NP-Complete et sa seule vraie stratégie (comme ici) est la force brute. Si je peux trouver les références pertinentes, je les ajouterai ici.
La meilleure référence que je puisse trouver est ici où Eric discute du fait que c'est le travail de résolution de surcharge qui cause le coût réel - rappelez-vous, Enumerable.Sum a 10 surcharges qui acceptent une méthode lambda /.
la source
10^n
combinaisons (oùn
est la quantité de méthodes enchaînées). Cela semble raisonnable (à titre d'explication, c'est-à-dire).that^numberofpossibletypes