Wenn Sie versuchen, den folgenden Code zu kompilieren, werden Sie feststellen, dass der Compiler> 3 GB RAM (der gesamte freie Speicher auf meinem Computer) und sehr lange Zeit zum Kompilieren benötigt (tatsächlich erhalte ich nach 10 Minuten eine E / A-Ausnahme).
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)))))));
}
}
Kann jemand dieses merkwürdige Verhalten erklären?
CS-Version: Microsoft (R) Visual C # Compiler Version 4.0.30319.17929 Betriebssystemname: Microsoft Windows 7 Ultimate Betriebssystemversion: 6.1.7601 Service Pack 1 Build 7601
Antworten:
Ich glaube, dass dies mit der Typinferenz und / oder der Lambda-Erzeugung zusammenhängt (wenn die Typinferenz in die entgegengesetzte Richtung zur Normalen gehen muss), kombiniert mit der Überlastungsauflösung. Leider hilft es nicht, nur die Typparameter anzugeben (wo vermutlich noch die Typprüfung durchgeführt werden muss).
Der folgende Code, der logischerweise der entsprechende Code von Ihnen sein sollte, wird nach der Analyse von Lambdas problemlos kompiliert:
Ich glaube, Eric Lippert hat geschrieben, bevor diese Typinferenz eine der Stellen im C # -Compiler ist, an denen (bestimmte Probleme) den Compiler zwingen können, ein NP-Complete-Problem zu lösen, und seine einzige wirkliche Strategie (wie hier) ist Brute Force. Wenn ich die relevanten Referenzen finde, füge ich sie hier hinzu.
Die beste Referenz, die ich finden kann, ist hier, wo Eric die Tatsache diskutiert, dass es die Überlastungsauflösungsarbeit ist, die die tatsächlichen Kosten verursacht - denken Sie daran, Enumerable.Sum hat 10 Überladungen, die ein Lambda / eine Lambda-Methode akzeptieren.
quelle
10^n
Kombinationen (won
ist die Anzahl der verketteten Methoden). Klingt vernünftig (als Erklärung).that^numberofpossibletypes