Frage

Die C # Sprachspezifikation beschreibt Typinferenz in Abschnitt § 7.5.2. Es ist ein Detail darin, dass ich nicht verstehe. Betrachten Sie den folgenden Fall:

// declaration
void Method<T>(T obj, Func<string, T> func);

// call
Method("obj", s => (object) s);

Sowohl die Microsoft und Mono C # Compiler richtig schließen T = object, aber mein Verständnis des Algorithmus in der Beschreibung würde scheitern T = string und dann ergeben. Hier ist, wie ich es verstehe:

Die erste Phase

  • Wenn Ei ist eine anonyme Funktion, ein expliziter Parameter Typinferenz (§7.5.2.7) von Ei zu Ti ist

    ? hat keine Auswirkung, da der Lambda-Ausdruck keine expliziten Parametertypen hat. Richtig?

  • Andernfalls, wenn Ei eine Art U hat und XI ist ein Wert, dann wird ein Parameter Untergrenze Inferenz ist aus U zu Ti.

    ? der erste Parameter von statischen Typ string, so dass diese string an die untere Grenze für T fügt hinzu, nicht wahr?

Die zweite Phase

  • All nicht fixiert Typ Variablen Xi, die dies nicht tun hängt von (§7.5.2.5) jeder Xj befestigt ist (§7.5.2.10).

    ? T ist nicht fixiert; T hängt nicht von irgendetwas ... so T festgelegt werden soll, nicht wahr?

§7.5.2.11 Fixing

  • Der Satz von Kandidatentypen Uj beginnt als die Menge aller Typen in der Menge der Grenzen für Xi.

    ? {string (untere Grenze)}

  • Wir prüfen dann jeweils für Xi gebunden wiederum: [...] Für jede untere Schranke U von Xi alle Arten Uj, auf die es keine implizite Konvertierung von U ist aus dem Kandidatensatz entfernt. [...]

    ? nichts aus dem Kandidatensatz entfernen, nicht wahr?

  • Wenn unter den verbleibenden Kandidaten Typen Uj ein eindeutiger Typ V, aus dem es eine implizite Konvertierung in alle anderen Kandidatentypen, dann wird Xi V festgelegt.

    ? Da es nur einen Kandidaten-Typ ist, ist dies vacuously wahr, so Xi zu string fixiert ist. Richtig?


Also, wo soll ich denn falsch?

War es hilfreich?

Lösung

UPDATE: Meine erste Untersuchung auf dem Bus heute Morgen war unvollständig und falsch. Der Text der ersten Phase Spezifikation ist richtig. Die Implementierung korrekt ist.

Die Spezifikation ist in falsch, dass es die Reihenfolge der Ereignisse falsch in der zweiten Phase kommt. Wir sollen spezifiziert werden, dass wir Ausgang Typinferenz machen vor wir die nicht-abhängigen Parameter zu beheben.

Man wird diese Sachen kompliziert. Ich habe diesen Abschnitt der Spezifikation mehrmals neu geschrieben als ich mich erinnern kann.

Ich habe dieses Problem schon einmal gesehen, und ich erinnere mich deutlich machen Revisionen, so dass der falsche Begriff „Variable vom Typ“ wurde überall mit „Typ-Parameter“ ersetzt. (Typ-Parameter sind nicht Lagerorte, deren Inhalt unterschiedlich sein kann, so dass es keinen Sinn macht, sie Variablen zu nennen.) Ich zugleich denke ich darauf hingewiesen, dass die Reihenfolge falsch war. Wahrscheinlich, was passiert war, dass wir versehentlich eine ältere Version der Spezifikation, die im Internet versandt. Viele Entschuldigungen.

Ich werde mit Mads arbeiten, um die Spezifikation zu erhalten aktualisiert, um die Umsetzung zu entsprechen. Ich denke, die korrekte Formulierung der zweiten Phase soll in etwa so gehen:

  • Wenn keine nicht fixierten Typ Parameter existieren dann Inferenz Typ erfolgreich ist.
  • Wenn andernfalls gibt es ein oder mehr Argumente Ei mit entsprechender Parameter Typ Ti, so dass der Ausgang Art von Ei mit Typ Ti enthält mindestens ein nicht fixiertes Typ-Parameter Xj und keine der Eingabetypen Ei mit Typ Ti enthält jede unfixierten Typ-Parameter Xj, dann wird ein Ausgang Typinferenz von allen solchen Ei zu Ti.

Ob der vorherige Schritt gemacht tatsächlich eine Folgerung, wir mindestens einen Typ Parameter fixieren muss nun wie folgt:

  • Wenn es gibt einen oder mehrere Typparameter Xi, so dass Xi ist nicht fixiert, und Xi hat einen nicht-leeren Satz von Grenzen, und Xi hängt nicht von jedem Xj dann jedes solches Xi ist fixiert. Sollte ein Befestigungsvorgang fehlschlägt, dann Typinferenz versagt.
  • Wenn andernfalls gibt es einen oder mehrere Typparameter Xi, so dass Xi ist nicht fixiert, und Xi hat einen nicht-leeren Satz von Grenzen, und es ist mindestens ein Typ-Parameter, die auf Xi Xj hängt dann jedes solches Xi ist fixiert. Sollte ein Befestigungsvorgang fehlschlägt, dann Typinferenz versagt.
  • Sonst sind wir nicht in der Lage, Fortschritte zu machen und es gibt nicht fixierten Parameter. Typinferenz versagt.

Wenn Inferenz Art weder versagt noch gelingt, dann wird die zweite Phase wiederholt wird.

Die Idee dabei ist, dass wir sicherstellen wollen, dass der Algorithmus nicht in eine Endlosschleife geht. Bei jeder Wiederholung der zweiten Phase gelingt es entweder versagt, oder macht Fortschritte. Es kann unmöglich Schleife öfter als es Typ Parameter Fix-Typen sind.

Vielen Dank für dieses Problem an Aufmerksamkeit.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top