2012-12-10 23 views
13

Czy można odrzucić niektóre argumenty w wyrażeniach lambda, nie nadając im nazwy? E.g. Muszę zdać Action < int, int >, ale jestem zainteresowany tylko w drugim param, chcę napisać coś podobnegoC# Bezimienne parametry lambda

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

w pierwszym przypadku to działa. Ale pierwszy parametr nie jest tak naprawdę nienazwany, ponieważ ma on nazwę "_". Więc to nie działa, kiedy chcę odrzucić dwa lub więcej. Wybieram _, ponieważ w prologu ma on znaczenie "dowolna wartość".

So. Czy jest jakaś specjalna postać lub wyrażenie do mojego przypadku użycia?

Odpowiedz

8

Nie, nie możesz. Patrząc na gramatykę C# language specification, istnieją dwa sposoby deklarowania lambd: jawne i niejawne. Żadne z nich nie pozwala na pominięcie identyfikatora parametru lub ponowne użycie identyfikatorów (nazw).

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

implicit-anonymous-function-parameter: 
    identifier 

Jest taki sam jak dla nieużywanych parametrów funkcji w zwykłych funkcjach. Trzeba im nadać imię.

Oczywiście można użyć _ jako nazwy dla jednego z parametrów, ponieważ jest to poprawna nazwa C#, , ale to nie znaczy nic specjalnego.

Od C# 7, _ma mają specjalne znaczenie. Nie dla nazw parametrów wyrażeń lambda, ale zdecydowanie dla innych rzeczy, takich jak dopasowywanie wzorców, dekonstrukcja, zmienne out, a nawet regularne przypisania. (Na przykład można użyć _ = 5, bez deklarowania _.)

+2

'_' * ma * ma specjalne znaczenie jak w C# 7. Nie dla nazw parametrów wyrażeń lambda (o ile wiem), ale zdecydowanie dla innych rzeczy, takich jak dopasowywanie wzorców, dekonstrukcja, zmienne 'out', a nawet regularne przypisania. (Na przykład, możesz użyć '_ = 5;' bez deklarowania '_'.) Rozumiem, że ta odpowiedź została napisana kilka lat przed C# 7, ale biorąc pod uwagę, że ostatnia linia stała się niepoprawna, dobrze byłoby ją edytować, jeśli masz czas. –

+1

@JonSkeet Dzięki za uwagę, dodałem Twoje komentarze w edycji. Muszę lepiej przewidzieć przyszłość. –

+0

Często znajduję się w tej samej pozycji - w tym przypadku nie zauważyłem, że była to stara odpowiedź od dłuższego czasu ... nowa odpowiedź postawiła pytanie na pierwszej stronie. –

5

Krótka odpowiedź brzmi: nie, musisz nazwać każdy parametr, a nazwy muszą być unikalne.

Możesz użyć _ jako jednej nazwy parametru, ponieważ jest to poprawny identyfikator w C#.
Można jednak użyć go tylko raz.

+4

Dlatego właśnie tak często kończę na '(_, __, ___, foo) => {...}' – Basic

0

W języku C# 7 można używać odrzutów. Odrzuty to zmienne tylko do zapisu, których nie można odczytać. Zasadniczo dla zmiennych, których nie chcesz używać, więcej szczegółów here

+1

Jest to prawda i została pominięta przez inne odpowiedzi, ale nie jest istotna w przypadku parametrów wyrażania lambda, o ile wiem. (Nie możesz użyć na przykład '(_, _, x) => x') –

+0

@JonSkeet, więc nie możesz tego użyć? (_, foo) => bar (foo) –

+1

Możesz, ale wtedy '_' jest zwykłym parametrem. Nie możesz użyć '(_, _, x)', ponieważ wtedy będziesz dwa razy zadeklarował ten sam parametr. (Podczas gdy możesz używać '_' wiele razy we wzorach.) –