Может ли лямбда-выражение C # содержать более одного оператора?

131

Может ли лямбда-выражение C # включать более одного оператора?

(Изменить: как указано в нескольких ответах ниже, в этом вопросе изначально задавались «строки», а не «утверждения».)

paseena
источник
17
Да, вы можете использовать несколько строк. Я не считаю правильным давать полный ответ.
Tesserex
1
@Tesserex - что бы не дать ему ответ ... ты прав!
RQDQ
3
@RQDQ Поскольку это вопрос «да» или «нет», я не думаю, что он достоин той репутации, которую можно получить в результате положительных голосов.
Tesserex

Ответы:

195

Конечно:

List<String> items = new List<string>();

var results = items.Where(i => 
            {
                bool result;

                if (i == "THIS")
                    result = true;
                else if (i == "THAT")
                    result = true;
                else
                    result = false;

                return result;
            }
        );
RQDQ
источник
31

(Я предполагаю, что вы действительно говорите о нескольких утверждениях, а не о нескольких строках.)

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

// Valid
Func<int, int> a = x => x + 1;
Func<int, int> b = x => { return x + 1; };        
Expression<Func<int, int>> c = x => x + 1;

// Invalid
Expression<Func<int, int>> d = x => { return x + 1; };
Джон Скит
источник
1
Я пытаюсь понять, почему Func разрешает фигурные скобки, а Expression не позволяет. В любом случае Expression будет выполняться как Func. Есть ли способ добавить многострочную логику в дерево выражений? Если нет, то почему это ограничение?
Habeeb
8
@Habeeb: «В любом случае Expression будет выполняться как Func» Не всегда. В большинстве случаев он вообще никогда не компилируется в делегат - просто рассматривается как данные. Деревья выражений в .NET 4.0 действительно получить возможность включать несколько операторов через Expression.Block , но C # язык не поддерживает это. Может, но для этого потребуется больше работы по проектированию / реализации / тестированию.
Джон Скит
26

Вы можете поместить в лямбда-выражение столько символов новой строки, сколько захотите; C # игнорирует символы новой строки.

Вероятно, вы хотели спросить о нескольких утверждениях .

Несколько операторов можно заключить в фигурные скобки.

Смотрите документацию .

SLaks
источник
17
Не было бы правильнее сказать, что C # одинаково обрабатывает все пробелы, включая символы новой строки? Сказать, что он игнорирует новые строки, звучит немного неверно - создается впечатление, что он просто их полностью удаляет, и вы можете разделить ключевое слово на новую строку или что-то в этом роде.
Tesserex
6

Начиная с C # 7:

Однострочный оператор:

int expr(int x, int y) => x + y + 1; 

Многострочный оператор:

int expr(int x, int y) { int z = 8; return x + y + z + 1; };

хотя они называются локальными функциями, я думаю, что это выглядит немного чище, чем приведенное ниже, и фактически то же самое

Func<int, int, int> a = (x, y) => x + y + 1;

Func<int, int, int> b = (x, y) => { int z = 8; return x + y + z + 1; };
BigChief
источник
4
Func<string, bool> test = (name) => 
{
   if (name == "yes") return true;
   else return false;
}
государственное устройство
источник
5
Func <string, bool> test = name => name == "yes";
asawyer
3
Polity демонстрирует многострочный формат, о котором идет речь в вопросе, а не развлекательные предложения по игре в гольф. Реализация вашего мудрого кода сделала бы его «не ответом»!
Caius Jard
0

С С # 7.0 вы также можете использовать это

Public string ParentMethod(int i, int x){
    int calculation = (i*x);
    (string info, int result) InternalTuppleMethod(param1, param2)
    {
        var sum = (calculation + 5);
        return ("The calculation is", sum);
    }
}
джигар праджапати
источник
0

Допустим, у вас есть класс:

    public class Point
    {
        public int X { get; set; }
        public int Y { get; set; }
    }

С C # 7.0 внутри этого класса вы можете сделать это даже без фигурных скобок:

Action<int, int> action = (x, y) => (_, _) = (X += x, Y += y);

и

Action<int, int> action = (x, y) => _ = (X += x, Y += y);

будет так же, как:

Action<int, int> action = (x, y) => { X += x; Y += y; };

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

public void Action(int x, int y) => (_, _) = (X += x, Y += y);

или

public void Action(int x, int y) => _ = (X += x, Y += y);

или

public void Action(int x, int y) => (X, Y) = (X + x, Y + y);

Подробнее о деконструкции кортежей в документации .

Konard
источник