2013-05-30 3 views
3

Это очень простой вопрос, я бы предположил, для тех, кто хорошо знает лямбда. Я только сейчас изучаю его и пробегаю одно выражение, которое для меня не имеет смысла.Сложность понимания конкретного выражения лямбды

Из того, что я понимаю, лямбда-выражения проходят в переменной, указанной на левой стороне, и запускают код справа. Например

myFunction = x => x + x; 

так туРипсЫоп (2) вернет 4.

Во всяком случае, я смотрел на Linq запрос на здесь и увидел это:

IEnumerable<int> numQuery2 = numbers.Where(num => num % 2 == 0).OrderBy(n => n); 

n => n ... что делает это? Почему бы просто не сказать OrderBy(n)? Все, что вы делаете, передает n в функцию, которая возвращает n. > _> Что здесь происходит?

+2

Предположим, что у вас есть функция 'int F (int x) {return x; } ', тогда вы можете использовать' .OrderBy (F) ' – I4V

+1

На более мягком языке: вы должны указать OrderBy, какой ключ или свойство вы хотите использовать для сортировки. Пример MSDN: 'IEnumerable query = pets.OrderBy (pet => pet.Age);'. Высказывать OrderBy (Pet) не помогло бы, так как OrderBy не знает, как устроить Pet. –

ответ

4

Давайте разберем это вниз:

numbers 

Это коллекция integers.

.Where(num => num % 2 == 0) 

Это говорит «найди мне все предметы в моей коллекции, где мой номерный модуль 2 = 0».

.OrderBy(n => n); 

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

Причина, по которой вам нужно n => n, заключается в том, что вы можете сортировать что-то другое, кроме значения. Скажем, например, длина элемента в виде строки

.OrderBy(n => n.ToString().Length) 

Очевидно, что для целых чисел, это не служит никакой цели. Но для других типов данных, таких как классы, это очень полезно.

+0

Спасибо за ответы! Твой и Джон Скит были оба очень информативны и идеально соответствовали моим потребностям, но вы получили первый пост, чтобы получить ответ! – user1548103

+2

@ user1548103: На самом деле мой пост был примерно на минуту раньше, но я бы не рекомендовал использовать время как способ определить, какой ответ принять в любом случае. Это должен быть самый * полезный * ответ, каким бы способом вы это ни выбрали.(Я не предлагаю вам переключаться с принятыми ответами - я просто предлагаю, чтобы время не было лучшим показателем для использования.) –

9

n => n ... Что это будет делать?

Он просто отображает любое значение для себя. Это функция идентификации.

Почему бы просто не сказать OrderBy (n)?

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

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

OrderByтребует проецирования от типа элемента к типу типа заказа - это просто, что в этом случае нам нужна проекция идентичности.

Вы можете написать свой собственный дополнительный метод расширения:

public static IEnumerable<T> OrderNaturally<T>(this IEnumerable<T> source) 
{ 
    return source.OrderBy(item => item); 
} 

А затем изменить оригинальное заявление:

IEnumerable<int> numQuery2 = numbers.Where(num => num % 2 == 0).OrderNaturally(); 

, если вы обнаружили, что более удобным для чтения.

В качестве альтернативы, вы можете создать Functions класс с некоторыми полезными статических полей только для чтения:

public static class Functions<T> 
{ 
    public static readonly Func<T, T> Identity = x => x; 
    public static readonly Func<T, T> DefaultValue => x => default(T); 
    public static readonly Func<T, string> ToString = x => x == null ? null : x.ToString(); 
    ... 
} 

Тогда:

IEnumerable<int> numQuery2 = numbers.Where(num => num % 2 == 0) 
            .OrderBy(Functions<int>.Identity) 

Я не думаю, что бы сделать это ... Я «Просто предлагаю подумать»

+0

Если вы измените его на 'Order', вы можете фактически использовать меньшее количество символов для объявления во всем своем коде, сохраняя при этом достаточную читаемость. Однако, если вы хотите иметь аналогичный метод расширения для 'ThenBy', метод' Then' для меня не читается, а 'ThenNaturally' будет вполне читаемым. –

+0

@TimS .: Нет, я бы не назвал это просто «Заказ» - это не объясняет это достаточно ясно, на мой взгляд. –

+0

Спасибо за ответ! Это помогло тонну! – user1548103

0

n => n означает, что функция принимает один аргумент ument, поскольку он вводит и возвращает его в качестве возвращаемого значения.

Почему бы просто не сказать OrderBy(n)

Как вы знаете, что n является лямбда? Какое указание, что это функция? Если у вас есть функция, названная n, которая приняла целое число и вернула то же самое целое число, то вы могли бы сделать это, но я предполагаю, что это не то, о чем вы думали.

Я знаю, что ты не просил, но:

Есть некоторые альтернативный синтаксис, что # компилятор C команда могла бы использовать для покрытия особого случая «идентичность лямбды»?

(«Идентификатор лямбда» - это технический термин для функции, которая возвращает только одно значение ввода).

Да. Они могли бы. Они этого не сделали, вероятно, потому, что они просто не считали, что это стоит времени/усилий, учитывая, что писать идентификационную функцию достаточно просто без специального синтаксиса.

Смежные вопросы