Warum einige C# - lambda-Ausdrücke kompilieren, um statische Methoden?
Wie Sie sehen können, im code unten habe ich erklärt, eine Action<>
Objekt als variable.
Wäre jemand bitte lassen Sie mich wissen, warum dieser action-Methode delegieren verhält sich wie eine statische Methode?
Warum es zurück true
im folgenden code?
Code:
public static void Main(string[] args)
{
Action<string> actionMethod = s => { Console.WriteLine("My Name is " + s); };
Console.WriteLine(actionMethod.Method.IsStatic);
Console.Read();
}
Ausgabe:
InformationsquelleAutor nunu | 2014-09-01
Du musst angemeldet sein, um einen Kommentar abzugeben.
Dies ist wahrscheinlich, denn es gibt keine Verschlüsse, zum Beispiel:
Dieser Ausgabe wird
false
fürwithClosure
undtrue
fürwithoutClosure
.Wenn Sie einen lambda-Ausdruck, der compiler erstellt eine kleine Klasse um die Methode, diese zusammenstellen würde etwas wie folgt aus (die tatsächlichen Umsetzung wahrscheinlich variiert leicht):
Sehen Sie die daraus resultierenden
Action<string>
Instanzen eigentlich Punkt-zu-Methoden auf diese generierten Klassen.static
Methoden.Ich wollte gerade vorschlagen, dass diese Frage brauchte einige expansion, kehrte ich zurück und da war es. Sehr informativ - schön zu sehen, was der compiler tut unter der Decke.
ist wirklich hilfreich für das Verständnis, was eigentlich vor sich geht, Neige ich dazu, verwenden Sie die
IL
RegisterkarteLINQPad
zu untersuchen, kleinen Proben.Würden Sie uns bitte sagen, wie hast du die compiler-Ausgabe? ILDASM nicht geben, solche Ausgabe.. Durch irgendein tool ODER software?
In diesem Beispiel habe ich die
IL
RegisterkarteLINQPad
, und zufällig C#. Einige Optionen, um die eigentlichen C# - äquivalent, das Gesamtergebnis wäre, die NutzungILSpy
oderReflector
auf die kompilierte assembly, würden Sie wahrscheinlich benötigen, um deaktivieren Sie einige Optionen, die versuchen, die Anzeige der Lambda-Ausdrücke und nicht den vom compiler generierten Klassen.InformationsquelleAutor Lukazoid
Den "action-Methode", ist statisch nur als Nebeneffekt der Umsetzung. Dies ist ein Fall von einer anonymen Methode, die mit nicht erfassten Variablen. Da gibt es keine Variablen erfasst, die Methode hat keine zusätzliche Lebensdauer Anforderungen über diejenigen hinaus, die für die lokalen Variablen im Allgemeinen. Wenn es einer Referenz zu anderen lokalen Variablen, die Lebensdauer erstreckt sich auf die Lebenszeit anderer Variablen (siehe ABS. L. 1.7, Lokale Variablen und Sek. N. 15.5.1, Erfasst äußeren Variablen, in der C# - 5.0-Spezifikation).
Beachten Sie, dass die C# - Spezifikation spricht nur über anonyme Methoden konvertiert, "expression trees", nicht "anonyme Klassen". Während der Ausdruck Baum dargestellt werden können, als zusätzliche C# - Klassen, beispielsweise in den Microsoft-compiler, diese Implementierung ist nicht erforderlich (bestätigt sec. M. 5.3 in der C# - 5.0-Spezifikation). Daher ist es undefiniert, ob die anonyme Funktion, die statisch ist oder nicht. Darüber hinaus, Abschnitt K. 6 lässt viel offen, wie die details des expression trees.
InformationsquelleAutor Peter O.
Delegieren caching-Verhalten wurde geändert in Roslyn. Vorher, wie gesagt, jeder lambda-Ausdruck, der nicht zu erfassen Variablen wurden in eine
static
- Methode mit dem Aufruf von site. Roslyn verändert dieses Verhalten. Nun, jeder lambda, erfasst, die Variablen oder nicht, verwandelt sich in einen Anzeige-Klasse:Angesichts dieses Beispiel:
Native compiler Ausgabe:
Roslyn:
Delegieren caching-Verhalten ändert sich in Roslyn spricht darüber, warum diese änderung vorgenommen wurde.
InformationsquelleAutor Yuval Itzchakov
Die Methode hat keine Verschlüsse und auch Verweise auf eine statische Methode selbst (Konsole.WriteLine), so würde ich erwarten, dass es zu statisch sein. Die Methode deklarieren, die einem umschließenden anonymen Typ für eine Schließung, aber in diesem Fall ist es nicht erforderlich.
InformationsquelleAutor Mel Padden
Als von C# 6 wird immer default-Methoden einer Instanz, und wird niemals statisch sein (also
actionMethod.Method.IsStatic
wird immer falsch sein).Siehe hier: Warum hat ein lambda-Ausdruck mit keinem capture verwandelt sich von einem statischen in C# 5, um eine Instanz-Methode in C# 6?
und hier: Unterschied in der CSC und die Roslyn compiler die statische lambda-Ausdruck Auswertung?
InformationsquelleAutor James Wilkins