Лямбда для Макетов … кто-либо, кто-либо?Я думаю, нет

В моих поисках для понимания очень нечетного взгляда '=>' оператор я нашел, что хорошее место запускается, и автор очень краток и ясен:

parameters => expression

У кого-либо есть какие-либо подсказки относительно понимания основ лямбд так, чтобы стало легче 'дешифровать' более сложные операторы лямбды?

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

filenames.SelectMany(f => 
        Assembly.LoadFrom(f).GetCustomAttributes(typeof(PluginClassAttribute), true)
        .Cast()
        .Select(a => a.PluginType)
).ToList();

Как я могу пойти о разламывании этого на более простые части?


ОБНОВЛЕНИЕ: требуемый для показа моего первого лямбда-выражения. Не смейтесь надо мной, но я сделал это, не копируя чей-то пример..., и это работало в первый раз:

public ModuleData[] GetStartModules( )
{ return modules.FindAll(start => start.IsBatch == true).ToArray(); }

36
задан ROMANIA_engineer 3 November 2017 в 21:18
поделиться

9 ответов

Давайте рассмотрим образец вашего кода:

filenames.SelectMany(f => 
        Assembly.LoadFrom(f).GetCustomAttributes(typeof(PluginClassAttribute), true)
        .Cast<PluginClassAttribute>()
        .Select(a => a.PluginType)
).ToList();

Итак, мы начнем с β string [] , называемых именами данных . Мы вызываем метод расширения SelectMany SelectMany на массиве, а затем мы вызываем TOLIST в результате:

filenames.SelectMany(
   ...
).ToList();

SelectMany принимает делегат в качестве параметра, в этом случае делегат должен Возьмите один параметр типа string в качестве ввода и возврата IENumerable (где выводится тип t ). Это где лямбдас вступает в сцену:

filenames.SelectMany(f => 
        Assembly.LoadFrom(f).GetCustomAttributes(typeof(PluginClassAttribute), true)
).ToList()

Что произойдет вот то, что для каждого элемента в массиве в массиве делегат будет вызван. F - это входной параметр, и все, что подойдет справа от => - это тело метода, который делегат относится к. В этом случае Assembly.load from будет вызывать имя файла в массиве, передавая его имя файла в метод loadFrom , используя аргумент f . В состав будет возвращено getCustomattribute (typeof (pluginclassattribute), true) , что возвращает атрибут Array . Таким образом, компилятор не может сделать вывод, что тип T , упомянутых ранее, является , .

на IENumerable , который возвращается, будет включен , будет вызван () , возвращается Ienumerable .

Итак, теперь у нас есть IENumerable , и мы вызовите . Выберите на нем . SELECT метод аналогичен SelectMany , но возвращает один экземпляр типа T (который выводится компилятором) вместо IENumerable < T> . Настройка идентична; Для каждого элемента в Ienumerable он будет вызывать определенный делегат, передавая значение текущего элемента в него:

.Select(a => a.PluginType)

снова, A - это входной параметр, A.PlugIntype - это тело метода. Итак, для каждого PluginClassattribute экземпляра в списке он вернет значение свойства PluclintyPe (я буду предположить, что это свойство имеет тип типа ).

Резюме
Если мы приклеиваем эти биты и куски вместе:

// process all strings in the filenames array
filenames.SelectMany(f => 
        // get all Attributes of the type PluginClassAttribute from the assembly
        // with the given file name
        Assembly.LoadFrom(f).GetCustomAttributes(typeof(PluginClassAttribute), true)
        // cast the returned instances to PluginClassAttribute
        .Cast<PluginClassAttribute>()
        // return the PluginType property from each PluginClassAttribute instance
        .Select(a => a.PluginType)
).ToList();

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

List<string> strings = new List<string> { "one", "two", "three" };

скажем, мы хотим отфильтровать те, которые начинаются с буквы «T»:

var result = strings.Where(s => s.StartsWith("t"));

Это самый распространенный подход; Установите его, используя лямбда выражение. Но есть альтернативы:

Func<string,bool> func = delegate(string s) { return s.StartsWith("t");};
result = strings.Where(func);

Это, по сути, то же самое: сначала мы создаем делегат типа FUNC (это означает, что он требует строки в качестве входного параметра, и возвращает A Bool ). Затем мы проходим этот делегат в качестве параметра к , где метод . Это то, что компилятор сделал для нас за кулисами в первом образце ( строк. Где (S => S.ctartswith («T»)); ).

Один третий вариант - просто передавать делегату к неанонимному методу:

private bool StringsStartingWithT(string s)
{
    return s.StartsWith("t");
}

// somewhere else in the code:
result = strings.Where(StringsStartingWithT);

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

И если у вас была энергия, прочитала все, что здесь, ну, спасибо за ваше время :)

40
ответ дан 27 November 2019 в 05:59
поделиться

Вычисление лямбды распространено во многих языках программирования. В некоторых языках их также называют анонимными функциями. Хотя разные языки имеют разный синтаксис лямбда, принцип один и тот же, и их различные части обычно одинаковы.

Возможно, наиболее известной из них являются анонимные функции Javascript.

lol = function() {laugh()}
# is equivalent to
function lol() {laugh()}

В чем разница? Ну, иногда не хочется создавать функцию только для того, чтобы раз и навсегда передать ее куда-нибудь.

window.onload = function() {laugh()}
# is way easier than
function lol() {laugh()}
window.onload = lol

Вы можете посмотреть статью в википедии для неразборчивой информации или вы можете перейти непосредственно к Lambda в программировании в той же статье.

0
ответ дан 27 November 2019 в 05:59
поделиться

AurioTouch - правильный пример. К сожалению, код просто ужасен. Убедитесь, что он используется только для ознакомления с концепциями работы с аудиоустройством RemoteIO.

Фактическое рисование формы сигнала происходит прямо в обратном вызове renderProc, который вызывается CoreAudio, когда становятся доступными данные PCM. Посмотрите на PerformThru () в aurioTouchAppDelegate.mm:197... далее вниз, в строке 237

SInt8 *data_ptr = (SInt8 *)(ioData->mBuffers[0].mData);

... здесь осуществляется доступ к фактическим данным ИКМ. Это данные, которые необходимо проанализировать для получения пиковой/средней мощности сигнала.

-121--3653551-

Написанный запрос выбирает атрибут f. Однако возвращать узел атрибута из XQuery недопустимо. Ошибка ссылается на выходной документ, который здесь содержит только атрибут (хотя это сообщение об ошибке вводит в заблуждение, так как технически здесь нет выходного документа, то возвращается только узел атрибута).

Вы, вероятно, хотели бы вернуть значение атрибута, а не самого атрибута

return data($foonode)
-121--2207907-

Одно хорошее простое объяснение, направленное на разработчиков, которые тверды в кодировании, но не в lambdas, это простое видео на TekPub

TekPub - Концепции: # 2 Lambdas

Вы

2
ответ дан 27 November 2019 в 05:59
поделиться

Я понимаю, что этот старый вопрос, но он может быть полезным.

  map.with_options(:path_prefix => ":locale") do |m|
    m.resources :posts
    m.resources :stories        
  end

И вы должны добавить перед фильтром к контроллеру приложения, чтобы определить язык, например,

before_filter :define_locale

def define_locale
  if params[:locale] == nil
    I18n.locale = 'en'
  else
    I18n.locale = params[:locale]
  end
end
-121--1625201-

С точки зрения базы данных вы должны быть более точными. Это RDBMS, ODBMS или большая сохраняемая хэш-таблица? Для меня файловая система также является своего рода "реализацией базы данных" (на основе иерархии и каталога/файла).

-121--4667703-

Итак, начать с страшного определения - лямбда - это еще один способ определения анонимного метода. Существует (с C # 2.0 я полагаю) способ построения анонимных методов - однако, что синтаксис был очень... неудобный.

Что такое анонимный метод? Это способ определения метода в линию, без имени - следовательно, анонимно. Это полезно, если имеется метод, который принимает делегат, так как можно передать лямбда-выражение/анонимный метод в качестве параметра, учитывая, что типы совпадают. Возьмем IEnumerable.Select в качестве примера, он определяется следующим образом:

IEnumerable<TResult> Select<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, TResult> selector);

Если этот метод обычно используется в списке и каждый элемент выбирается дважды (что связано с самим собой):

string MyConcat(string str){
    return str + str;
}

...

void myMethod(){
    IEnumerable<string> result = someIEnumerable.Select(MyConcat);
}

Это очень неудобный способ сделать это, особенно если вы хотите выполнить многие из этих операций - также обычно такие методы вы используете только один раз. Показанное определение (parameters = > expression) очень смыслово и попадает в пятно. Интересным в лямбде является то, что не нужно выражать тип параметров - , пока они могут быть выведены из выражения . Т.е. в случае Select - мы знаем , что первый параметр должен иметь тип TSource - потому что определение метода так и утверждает. Дальше больше - если мы назовем метод так же, как foo. Выберите (...), затем возвращаемое значение выражения определит TResult.

Интересно также то, что для лямбды с одним оператором не требуется ключевое слово return - лямбда возвращает все, что вычисляет одно выражение. Однако если используется блок (заключенный в "" {"" и ""} ""), необходимо включить ключевое слово return, как обычно.

Если вы хотите, по-прежнему 100% законно определять типы параметров. С этим новым знанием попробуем переписать предыдущий пример:

void myMethod(){
    IEnumerable<string> result = someIEnumerable.Select(s => s + s);
}

Или, с явными параметрами, заявленными

void myMethod(){
    IEnumerable<string> result = someIEnumerable.Select((string s) => s + s);
}

Еще одна интересная особенность лямбды в C # - их использование для построения деревьев выражений . Это, вероятно, не "начинающий" материал, но короче говоря, дерево выражений содержит все метаданные о лямбде, а не исполняемый код.

6
ответ дан 27 November 2019 в 05:59
поделиться

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

private int sum5(int n)
{
    return n + 5;
}

эквивалентен лямбде: (n) => n + 5 . Кроме того, что метод можно вызвать где угодно в классе, а лямбда живет только в объявленной области видимости (можно также хранить лямбды в объектах Action и Func)

Другая вещь, которую лямбды могут сделать для вас, это захват области видимости, построение закрытия. Например, если у вас есть что-то подобное:

...methodbody
int acc = 5;
Func<int> addAcc = (n) => n + acc;

То, что у вас есть, есть функция, которая, как и раньше, принимает аргумент, но добавляемая сумма берётся из значения переменной. лямбда может жить даже после того, как будет закончена область видимости, в которой была определена acc.

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

5
ответ дан 27 November 2019 в 05:59
поделиться

Мой совет для понимания Основы лямбдас - это два раза.

Во-первых, я рекомендую узнать о функциональном программировании. Haskell - хороший язык, чтобы начать с этим уважением. Книга, которую я использую, и вы получаете много, это программирование в Haskell Graham Hutton. Это дает хорошее заземление в Haskell и включает в себя объяснения лямбдаса.

Оттуда я думаю, что вы должны просмотреть лекции Эрика Мейера на функциональном программировании , так как они дают отличное введение в функциональное программирование, а также используя Haskell и пересекать в C #.

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

0
ответ дан 27 November 2019 в 05:59
поделиться

Аннотация метода @ ModelAttribute предназначена для предоставления ссылочных данных слою представления. Я не могу сказать точно в вашем случае, но я бы не сказал, что коллекция пользователей квалифицирована как справочные данные. Рекомендуется явно передать эту информацию модели в методах обработчика @ RequestMapping .

Если вы по-прежнему хотите использовать @ ModelAttribute , здесь есть запись блога , в которой обсуждается проблема перенаправления.

Но все предыдущие примеры имеют общая проблема, как all @ ModelAttribute методы выполняются до того, как обработчик выполнено, если обработчик возвращает перенаправление данных модели будет добавлено в URL-адрес в виде последовательности запроса. Это следует избегать любой ценой, как это может раскрыть некоторые секреты о том, как вы собрали вашу заявку.

Предложенное им решение (см. часть 4 блога) заключается в использовании HandableIntercepterAdapter , чтобы сделать общие ссылочные данные видимыми для просмотра. Поскольку эталонные данные не должны быть тесно связаны с контроллерами, это не должно создавать проблем с точки зрения конструкции.

-121--987668-

$ знак не является частью javascript он является частью javascript рамки вероятно, jQuery

Дополнительные сведения см. в этой статье

-121--2873411-

В последнее время у CodeProject была хорошая вводная статья: C # Делегаты, анонимные методы и лямбда-выражения - O My!

0
ответ дан 27 November 2019 в 05:59
поделиться

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

a => a + 1

Создает функцию, которая связывает свободную переменную A в выражении (A + 1) к первому параметру функции и возвращает эту функцию.

Один случай, когда лямбдас чрезвычайно полезен, заключается в том, что вы используете их для работы со структурами списка. Класс System.linq.enumerable предоставляет много полезных функций, которые позволяют работать с выражениями лямбда и объектами, реализующими iEnumerable. Например, перечисление. Где можно использовать для фильтрации списка:

List<string> fruits = new List<string> { 
        "apple", "passionfruit", "banana", "mango", 
        "orange", "blueberry", "grape", "strawberry" };

IEnumerable<string> shortFruits = fruits.Where(fruit => fruit.Length < 6);

foreach (string fruit in shortFruits) {
    Console.WriteLine(fruit);
}

Выход будет «Apple, Mango, Grape».

Старайтесь понять, что здесь происходит: фрукт выражения => фрукты. <6 создает функцию, которая возвращает true , если свойство длины параметра составляет менее 6 6

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

2
ответ дан 27 November 2019 в 05:59
поделиться

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

Оригинальное нотация, изобретенное Церковью Алонзо для его лямбда-исчисления в 1930-х годах использовала греческий характер лямбда в выражении λx.t , чтобы представлять функцию Отсюда и название.

0
ответ дан 27 November 2019 в 05:59
поделиться
Другие вопросы по тегам:

Похожие вопросы: