C # Синтаксис лямбда-выражения: нужны скобки? - PullRequest
14 голосов
/ 05 июня 2010

Я новичок в C #, и раньше я видел лямбда-выражение как

(params) => { expression;}

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

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

Без скобок.

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

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

Ответы [ 3 ]

25 голосов
/ 05 июня 2010

Правила:

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

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

Давайте сначала рассмотрим левую сторону.

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

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

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

Это все правила для списков параметров. Правила о правой стороне:

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

x => { return x + 1; }

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

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); }

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

15 голосов
/ 05 июня 2010

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


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

(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
5 голосов
/ 05 июня 2010

Скобки нужны только при наличии нескольких параметров.

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...