Jeśli mam lambdę taką jak () => { throw new Exception(); }
, nie jest jasne, czy ma ona typ powrotu, czy nie. Z tego powodu może być (niejawnie) przekonwertowany zarówno na Action
i Func<object>
(lub dowolny inny Func<T>
). Ma to miejsce dlatego, że zgodnie z § 6.5 Anonymous konwersji funkcji z C# 4 specyfikacji:Konwersja Lambda z niejasnym typem powrotu i rozdzielczością przeciążenia
[A], pełnomocnik typu
D
jest zgodny z anonimową funkcjęF
warunkiem, że:
...
Jeśli
D
mavoid
typ zwrotu, a treśćF
jest blokiem instrukcji, gdy [...] treścią jestF
jest poprawnym blokiem instrukcji, w którym żadna instrukcja return nie określa wyrażenia.Jeśli
D
ma nie zwracać typ void i ciałoF
jest blok oświadczenie, gdy [...] ciałoF
jest ważny blok oświadczenie o nie osiągalnego punktu końcowego, w którym każdyreturn
Instrukcja Określa wyrażenie, które jest niejawnie zamienne na typ zwrotuD
.
Ale jeśli dwie przeciążeń dotyczące sposobu, w której ma się parametr typu Action
a drugi Func<object>
, i przekazać je lambda od powyżej, stosuje się przeciążenia Func<object>
. Czemu? Która część specyfikacji mówi, że w tym przypadku Func<object>
jest lepsza niż Action
?
Przyjrzałem się § 7.5.3.2 Lepszy członek funkcji, ale to nie wyjaśnia.
A jeśli zamiast składni lambda, należy użyć notacja 'delegate {throw new Exception(); } 'gdzie pominąć listę parametrów w nawiasach'() ', że anonimowa funkcja może pasować ** dowolnie ** podpis delegata, w tym także np. Obiekty 'EventHandler' i' Action <, EventArgs> '. –
@JeppeStigNielsen Yeah. W takim przypadku tak naprawdę nie ma reguły, która pozwalałaby je rozróżnić jako parametry metody, więc powstałby błąd kompilacji. – svick