Синтаксис выражения С# Lambda: нужны ли скобки?

Я новичок в С#, и раньше я видел, что выражение лямбда похоже на

(params) => { expression;}

но в LINQ я видел такие примеры, как

IEnumerable<string> customerFirstNames = customers.Select(cust => cust.FirstName);

Без скобок.

Являются ли они одинаковыми или есть какая-то разница?

Большое спасибо.

Ответы

Ответ 1

Правила:

Лямбда-выражение имеет вид

( modifier type parameter, modifier type parameter ...) => { statements }

Рассмотрим сначала левую часть.

Модификатором может быть ref, out или ничего вообще.

Если нет модификаторов ref или out, все типы могут быть удалены. Если есть какие-либо модификаторы ref или out, то каждое объявление параметра должно иметь объявленный тип. Если какой-либо параметр имеет объявленный тип, то каждый параметр должен иметь объявленный тип. Таким образом, вы можете элиминировать типы, если (1) нет ссылок или выходов, и (2) вы удаляете все из них. В противном случае вы должны предоставить все типы.

Если имеется ровно один параметр и его тип был отменен, скобки вокруг списка параметров также могут быть исключены.

Что все правила о списках параметров. Правила правой стороны:

если список операторов состоит из одного оператора return с выражением:

x => { return x + 1; }

тогда можно скопировать фигурные скобки, ключевое слово return и точку с запятой:

x => x + 1

Кроме того, если список операторов состоит из одного оператора, который является выражением оператора:

x => { x++; } // Not returning the value of x++; only useful for the side effects
x => { new Y(x); } // weird! executing a ctor only for its side effects! But legal!
x => { M(x); } // note, not returning the value of M(x) even if there is one.

тогда также законно удалять фигурные скобки и точку с запятой:

x => x++
x => new Y(x)  
x => M(x)

Обратите внимание, что теперь это потенциально означает что-то другое для читателя! Прежде чем мы явно отбросили возвращаемые значения; теперь лямбды будут прочитаны как возвращающие их.

Обратите внимание, что это означает, что законно делать этот трюк с помощью методов возврата пустоты. Это действительно законно:

x => Console.WriteLine(x)

Тьфу. Не делай этого. Если вы имеете в виду

x => { Console.WriteLine(x); } 

тогда скажите, что вместо этого. Первый выглядит слишком сильно, как вы пытаетесь сказать

x => { return Console.WriteLine(x); }

который, конечно, был бы незаконным.

Ответ 2

В каких скобках вы говорите? ( ) или { }?


( ) используются в списке параметров и требуются, если у вас есть несколько параметров:

(a, b, c) => ...

Вы можете опустить их, когда у вас есть только один аргумент:

a => ...

{ } позволяют помещать блок выражений в тело лямбда-выражений:

(a, b, c) => {
                 Console.WriteLine("Hello World!");
                 Console.WriteLine("a = {0}", a);
                 Console.WriteLine("b = {0}", b);
                 Console.WriteLine("c = {0}", c);
                 return a * b + c;
             }

Без них тело лямбда-выражения является выражением :

(a, b, c) => a * b + c

Ответ 3

Вам нужны только скобки, если у вас несколько параметров.

Обновить (как это принято в SO, когда ответы редактируются после того, как другие люди ответили...)

Использование скобок (скобки "()" и фигурных скобок "{}" ) в этом случае является избыточным. Утверждения эквивалентны. Надстройка Visual Studio, такая как ReSharper, будет указывать на избыточность:

http://www.jetbrains.com/resharper/