как мне перевести "результат var" лямбда-выражения в пригодный для использования объект, который я могу затем распечатать результат?
Прежде всего, «лямбда-выражение» - это только часть выражения, имеющая форму a=>b
. Остальная часть вашего запроса - это просто вызов метода, который принимает лямбду в качестве аргумента.
В любом случае, если бы я мог научить людей одной вещи о LINQ, это было бы так: «результат» - это не результаты запроса, это - это сам запрос .
Если вы хотите увидеть результаты, задайте запрос для каждого результата:
foreach(var item in result)
Console.WriteLine(item.ToString());
Я также был бы признателен за подробное объяснение того, что происходит, когда я объявляю external => external.Value.Frequency
Конечно. Мы начинаем с разработки типов всего, что с этим связано. Мы видим, что лямбда-это функция, которая принимает KeyValuePair и возвращает int, поэтому мы генерируем метод
static private int MyLambda(KeyValuePair<int, FrequencyAndValue> outer)
{
return outer.Value.Frequency;
}
Затем мы возьмем этот метод и создадим из него делегата:
var result = dictionary.OrderByDescending(
new Func<KeyValuePair<int, FrequencyAndValue>, int>(MyLambda));
и переписать вызов метода расширения:
var result = Enumerable.OrderByDescending<KeyValuePair<int, FrequencyAndValue>, int>(
dictionary,
new Func<KeyValuePair<int, FrequencyAndValue>, int>(MyLambda));
и переписать переменную:
IOrderedEnumerable<KeyValuePair<int, FrequencyAndValue>> result =
Enumerable.OrderByDescending<KeyValuePair<int, FrequencyAndValue>, int>(
dictionary,
new Func<KeyValuePair<int, FrequencyAndValue>, int>(MyLambda));
Надеюсь, вы согласитесь, что код, который вы набрали, намного более читабелен, чем этот беспорядок. Тип выводных камней.
Результатом является объект, который представляет возможность сортировать этот словарь по заданному ключу. Внимательно прочитайте: это означает способность сортировать словарь по этому ключу. На самом деле он этого не делает, пока вы не попросите результат; до сих пор все, что это - объект, который говорит: «когда запрашивается результат, отсортируйте словарь по этому ключу».
Предположим, вы просите о результате. Как он вычисляет отсортированный список? Он запрашивает словарь для каждого элемента. Затем он вызывает MyLambda для каждого элемента, который возвращает целое число, поэтому у нас теперь есть пара словарных значений и целых чисел в словаре. Затем он строит список пар, отсортированных по этому целому числу. Затем он раздает элементы этого списка по одному, как вы их просите.
Мы видим, что лямбда-функция - это функция, которая принимает KeyValuePair и возвращает целое число "- Как вы это определили? Я не вижу его по возвращаемому значению метода или документально подтверждено в OrderByDescending ().
Ах, я вижу замешательство; по педагогическим соображениям я выдвинул немного выше относительно точного порядка, в котором происходит семантический анализ.
Как мы делаем этот вывод типа, является одной из наиболее тонких и интересных частей C #.
Вот как это работает.
Мы видим, что OrderByDescending объявлен как:
static IOrderedEnumerable<T> OrderByDescending<T, K>(
this IEnumerable<T> sequence,
Func<T, K> keyExtractor)
и мы видим, что у нас есть потенциальный вызов этого метода:
OrderByDescending(dictionary, o=>o.Value.Frequency)
Но мы не знаем, что такое Т и К. Итак, мы начнем с рассмотрения всего, что НЕ является лямбдой. Ваш словарь реализует IEnumerable<KeyValuePair<int, FrequencyOrValue>>
, поэтому мы начнем с того, что "T, вероятно, KeyValuePair<int, FrequencyOrValue>
".
На данный момент больше ничего мы не можем вывести из вещей, которые не являются лямбдами, поэтому мы начинаем смотреть на лямбды. Мы видим, что у нас есть лямбда o=>o.Value.Frequency
, и до сих пор мы определили, что типом keyExtractor является Func<KeyValuePair<int, FrequencyOrValue>, K>
, и мы все еще ищем K. Итак, мы говорим, предположим, что лямбда на самом деле была:
(KeyValuePair<int, FrequencyOrValue> o)=>{return o.Value.Frequency;}
И мы спрашиваем это связывает ? ДА! Да, это так. Мы можем успешно скомпилировать эту лямбду без ошибок, и когда мы делаем это, мы видим, что все ее операторы возврата возвращают int.
Поэтому мы выводим, что K - это int, и теперь у нас есть полный анализ типа всего этого.
Это довольно простой вывод; они могут стать намного страннее. Смотрите архив «вывод типа» в моем блоге, если эта тема особенно вас интересует.
http://blogs.msdn.com/ericlippert/archive/tags/Type+Inference/default.aspx
В частности, вот мое видео, объясняющее вышеизложенное, а также несколько других интересных случаев:
http://blogs.msdn.com/ericlippert/archive/2006/11/17/a-face-made-for-email-part-three.aspx