2012-12-10 16 views
13

ist es möglich, einige Argumente in Lambda-Ausdrücken zu verwerfen, indem Sie ihnen keinen Namen geben? Zum Beispiel Ich habe eine Aktion < int passieren, int >, aber ich bin daran interessiert sind nur in der zweiten param, ich möchte so etwas wieC# lambda unbenannte Parameter

(_, foo) => bar(foo) 
// or 
(, foo) => bar(foo) 

Im ersten Fall schreiben es funktioniert. Aber der erste Parameter ist nicht wirklich ungenannt, weil er den Namen "_" hat. Es funktioniert also nicht, wenn ich zwei oder mehr verwerfen möchte. Ich wähle _, weil es im Prolog die Bedeutung "beliebiger Wert" hat.

So. Gibt es einen speziellen Charakter oder Ausdruck für meinen Anwendungsfall?

Antwort

8

Nein, das geht nicht. Mit Blick auf die Grammatik C# language specification gibt es zwei Möglichkeiten, lambdas zu deklarieren: explizit und implizit. Bei beiden Methoden können Sie den Bezeichner des Parameters nicht überspringen oder Kennungen (Namen) erneut verwenden.

explicit-anonymous-function-parameter: 
    anonymous-function-parameter-modifieropt type identifier 

implicit-anonymous-function-parameter: 
    identifier 

Es ist das gleiche wie für nicht verwendete Funktionsparameter in normalen Funktionen. Sie müssen einen Namen erhalten.

Natürlich können Sie _ als den Namen für einen der Parameter verwenden, da es ein gültiger C# Name ist, , aber es bedeutet nichts besonderes.

Ab C# 7, _hat eine besondere Bedeutung. Nicht für Lambda-Ausdruck-Parameternamen, aber definitiv für andere Dinge, wie Mustererkennung, Dekonstruktion, Out-Variablen und sogar reguläre Zuordnungen. (Sie können z. B. _ = 5 verwenden, ohne _ zu deklarieren.)

+2

'_' * hat * eine besondere Bedeutung wie in C# 7. Nicht für Lambda-Expression-Parameternamen (soweit ich das beurteilen kann), aber definitiv für andere Dinge, wie Mustererkennung, Dekonstruktion, out-Variablen und sogar reguläre Zuweisungen. (Zum Beispiel können Sie '_ = 5;' verwenden, ohne '_' zu deklarieren.) Ich weiß, dass diese Antwort einige Jahre vor C# 7 geschrieben wurde, aber da die letzte Zeile falsch geworden ist, wäre es gut, diese zu bearbeiten Du hast Zeit. –

+1

@JonSkeet Danke für's Bemerken, ich habe deine Kommentare in einer Bearbeitung hinzugefügt. Ich muss besser darin werden, die Zukunft vorherzusagen. –

+0

Ich bin oft in der gleichen Position - in diesem Fall hatte ich nicht wirklich bemerkt, dass es eine alte Antwort für eine ganze Weile war ... die neue Antwort hatte die Frage auf die Titelseite gestellt. –

5

Die kurze Antwort lautet: Nein, Sie müssen jeden Parameter benennen, und die Namen müssen eindeutig sein.

Sie können _ als einen Parameternamen verwenden, da es ein gültiger Bezeichner in C# ist.
Sie können es jedoch nur einmal verwenden.

+4

Was ist, warum ich so oft enden mit '(_, __, ___, foo) => {...}' – Basic

0

In C# 7 können Sie Rückwürfe verwenden. Verwerfungen sind schreibgeschützte Variablen, die Sie nicht lesen können. Es ist im Grunde für Variablen, die Sie nicht verwenden möchten mehr Details here

+1

Dies ist wahr und wurde von anderen Antworten übersehen, ist aber im Falle von Lambda-Expressionsparametern nicht relevant, soweit ich das beurteilen kann. (Sie können zum Beispiel nicht '(_, _, x) => x' verwenden.) –

+0

@JonSkeet Sie können das also nicht verwenden? (_, foo) => bar (foo) –

+1

Sie können, aber dann '_' ist nur ein normaler Parameter. Sie können '(_, _, x)' nicht verwenden, weil Sie dann denselben Parameter zweimal deklarieren würden. (Während Sie '_' mehrfach in Mustern verwenden können.) –

Verwandte Themen