Warum können Sie in einem Lambda-Ausdruck keinen ref- oder out-Parameter verwenden?
Ich bin heute auf den Fehler gestoßen und habe eine Problemumgehung gefunden, war aber immer noch neugierig, warum dies ein Fehler beim Kompilieren ist.
CS1628 : Der Parameter 'parameter' in ref oder out kann nicht in einer anonymen Methode, einem Lambda-Ausdruck oder einem Abfrageausdruck verwendet werden
Hier ist ein einfaches Beispiel:
private void Foo()
{
int value;
Bar(out value);
}
private void Bar(out int value)
{
value = 3;
int[] array = { 1, 2, 3, 4, 5 };
int newValue = array.Where(a => a == value).First();
}
Antworten:
Lambdas scheinen die Lebensdauer der von ihnen erfassten Variablen zu ändern. Beispielsweise bewirkt der folgende Lambda-Ausdruck, dass der Parameter p1 länger als der aktuelle Methodenrahmen lebt , da auf seinen Wert zugegriffen werden kann, nachdem sich der Methodenrahmen nicht mehr auf dem Stapel befindet
Eine weitere Eigenschaft erfasster Variablen ist, dass Änderungen an der Variablen auch außerhalb des Lambda-Ausdrucks sichtbar sind. Zum Beispiel die folgenden Drucke 42
Diese beiden Eigenschaften erzeugen eine Reihe von Effekten, die auf folgende Weise einem ref-Parameter entgegenwirken
Dies sind etwas inkompatible Eigenschaften und einer der Gründe, warum sie in Lambda-Ausdrücken nicht zulässig sind.
quelle
ref
Lambda-Ausdruck nicht verwenden können , aber der Wunsch, ihn zu verwenden, wurde nicht gestillt.Unter der Haube wird die anonyme Methode implementiert, indem erfasste Variablen (worum es in Ihrem Fragetext geht) angehoben und als Felder einer vom Compiler generierten Klasse gespeichert werden. Es gibt keine Möglichkeit, einen
ref
oderout
Parameter als Feld zu speichern . Eric Lippert hat es in einem Blogeintrag besprochen . Beachten Sie, dass es einen Unterschied zwischen erfassten Variablen und Lambda-Parametern gibt. Sie können "formale Parameter" wie die folgenden haben, da diese keine erfassten Variablen sind:quelle
Sie können aber Sie müssen explizit alle Typen so definieren
Ist jedoch ungültig
Ist gültig
quelle
ref
oderout
sich in einem Lambda befindet. Es ist klar, ob Sie den Beispielcode lesen (versuchen Sie es erneut, um ihn erneut zu lesen). Die akzeptierte Antwort erklärt klar warum. Bei Ihrer Antwort geht es um die Verwendungref
oderout
Parameter des Lambda. Völlig nicht die Frage beantworten und über etwas anderes sprechenDa dies eines der Top-Ergebnisse für "C # lambda ref" bei Google ist; Ich denke, ich muss die obigen Antworten erweitern. Die ältere (C # 2.0) anonyme Delegatensyntax funktioniert und unterstützt komplexere Signaturen (sowie Schließungen). Lambdas und anonyme Delegierte haben zumindest die wahrgenommene Implementierung im Compiler-Backend geteilt (wenn sie nicht identisch sind) - und vor allem unterstützen sie Schließungen.
Was ich bei der Suche versucht habe, um die Syntax zu demonstrieren:
Denken Sie daran, dass Lambdas prozedural und mathematisch sicherer sind (aufgrund der bereits erwähnten Referenzwertförderung): Sie könnten eine Dose Würmer öffnen. Überlegen Sie genau, wenn Sie diese Syntax verwenden.
quelle
(a, b, c, ref d) => {...}
undref
wurde mit der Fehlermeldung "Parameter '4' muss mit dem Schlüsselwort 'ref' deklariert werden" rot unterstrichen. Gesichtspalme! PS Was ist "Ref Value Promotion"?Und vielleicht das?
quelle