Лямбда-выражение общий синтаксис - PullRequest
4 голосов
/ 12 октября 2009

Могу ли я следовать какому-нибудь простому synax или правилам для построения "лямбда-выражения" в C #? Я прочитал несколько статей и понял, что такое лямбда-выражение, но если бы у меня был общий синтаксис или правила, это было бы полезно.

Ответы [ 2 ]

10 голосов
/ 12 октября 2009

Существует несколько способов выражения лямбд, в зависимости от точного сценария - несколько примеров:

    // simplest form; no types, no brackets
    Func<int, int> f1 = x => 2 * x;
    // optional exlicit argument brackets
    Func<int, int> f2 = (x) => 2 * x;
    // optional type specification when used with brackets
    Func<int, int> f3 = (int x) => 2 * x;
    // multiple arguments require brackets (types optional)
    Func<int, int, int> f4 = (x, y) => x * y;
    // multiple argument with explicit types
    Func<int, int, int> f5 = (int x, int y) => x * y;

Подпись лямбды должна соответствовать подписи используемого делегата (будь то явная, как указано выше, или подразумеваемая контекстом в таких вещах, как .Select(cust => cust.Name)

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

    // no arguments
    Func<int> f0 = () => 12;

В идеале выражение с правой стороны - именно это; единое выражение. Компилятор может преобразовать это в или a delegate или в Expression дерево:

    // expression tree
    Expression<Func<int, int, int>> f6 = (x, y) => x * y;

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

    // braces for a statement body
    Func<int, int, int> f7 = (x, y) => {
        int z = x * y;
        Console.WriteLine(z);
        return z;
    };

Обратите внимание, что хотя деревья .NET 4.0 Expression поддерживают тела операторов, компилятор C # 4.0 не делает это за вас, поэтому вы по-прежнему ограничены простыми деревьями Expression, если только вы сделать это "трудным путем"; см. мою статью о InfoQ для получения дополнительной информации.

8 голосов
/ 12 октября 2009

Лямбда-выражение, по сути, является сокращенной записью для указателя функции. Чаще всего лямбда-выражение представляет собой распространение входных данных в выражение, которое вычисляет результат. В большинстве случаев вы будете использовать лямбда-выражения в их более обычной форме:

int[] numbers = new[] { 1, 3, 11, 21, 9, 23, 7, 4, 18, 7, 7, 3, 21 };

var twentyoneCount = numbers.Where(n => n == 21).Count();
var sumOfgreaterThanSeven = numbers.Sum(n => n > 7 ? n : 0);

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

myButton.Click += new EventHandler(myButton_Click);
// ...
void myButton_Click(object sender, EventArgs e)
{
    // TODO: Implement button click handler here
}

Или менее распространенное и менее многословное:

myButton.Click += delegate(object sender, EventArgs e)
{
    // TODO: Implement button click handler here
};

Следующее лямбда-выражение достигает того же результата, что и два предыдущих:

myButton.Click += (s,e) =>
{
    // TODO: Implement button click handler here
};

Сила этой последней формы действительно заключается в ее способности создавать замыкания. Закрытие - это то, где вы реализуете функцию внутри функции и «закрываете» вокруг параметров и переменных из области родительской функции:

private void DoSomething(IList<string> input, SomeObject source)
{
    source.OnSomeEvent += (s,e) => return input.Sum();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...