Для какой проблемной области создан LINQ?


12

Каждый раз, когда я вижу вопрос, опубликованный в Stack Overflow на C #, я вижу по крайней мере один или два опубликованных ответа, которые решают проблему с LINQ. Обычно люди с очень высокой репутацией используют LINQ как профессионалы.

Итак, мой вопрос: для какой проблемной области предполагается использовать LINQ?

Также на примечаниях стороны: Есть ли какие-либо цели, в которых это следует избегать? Влияет ли размер набора данных на производительность запросов LINQ?



Затем перейдите по ссылке: msmvps.com/blogs/jon_skeet/archive/tags/Edulinq/default.aspx
Одед

1
LINQ предназначен для запроса графов объектов. Это Language INtegrated Query - он позволяет запрашивать и управлять коллекциями.
Одед

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

1
Линк декларативен. Вы заявляете «что» вы хотите без указания «как» это сделано. Для linq это означает, что вы можете использовать запросы, чтобы указать, что вы хотите. Декларативный код может быть короче и проще для понимания некоторых проблем.
mike30

Ответы:


16

LINQ в первую очередь предназначен для обеспечения чисто функциональных запросов и преобразований в последовательности данных (вы заметите, что все расширения LINQ принимают делегаты Func, но не делегаты Action). Следовательно, наиболее распространенным случаем цикла, который не очень хорошо подходит для LINQ, является случай, связанный с не чисто функциональными побочными эффектами, например

foreach(var x in list) Console.WriteLine(x);

Чтобы лучше использовать LINQ, просто попрактикуйтесь в его использовании.

Каждый раз, когда вы собираетесь написать цикл forили foreachцикл, чтобы сделать что-то с коллекцией, остановитесь, подумайте, хорошо ли это подходит для LINQ (т.е. это не просто выполнение действия / побочного эффекта над элементами), и если это так, заставьте себя писать это с помощью LINQ.

Вы также можете foreachсначала написать версию, а затем переписать в версию LINQ.

Как указывает svick, LINQ должен сделать вашу программу более читабельной. Обычно это хорошо, так как имеет тенденцию подчеркивать намерения кода, а не механизм; однако, если вы обнаружите, что не можете сделать свои запросы более читабельными, чем простой цикл, не стесняйтесь придерживаться цикла.

Если вам нужны упражнения для практики, большинство упражнений по функциональному программированию будут хорошо отображаться в LINQ, например, 99 задач (особенно первые 20 или около того) или проект Эйлера .


Возможно, мне придется удалить этот вопрос сейчас. Модератор отметил, что он не подходит для сообщества. Если вы чувствуете иначе, пожалуйста, скажите мне.
user1816120

1
Я бы добавил, что если вы переписываете его в LINQ, а оригинал еще удобнее для чтения, сохраните оригинал и удалите версию LINQ. Иногда LINQ просто ничего не добавляет.
svick

@ svick в теории да, я не уверен, что могу придумать какие-либо примеры этого;)
JK.

1
@jk. Например, ReSharper иногда предлагает конвертировать мой цикл в LINQ, используя Aggregate(). Я думаю, что большую часть времени цикл более читабелен.
svick

@svick, вероятно, проблема того, к чему вы привыкли, хотя я признаю, что агрегат - это неуклюжее название для fold
jk.

1

Чтобы ответить на отредактированный вопрос: короче говоря, полезно использовать LINQ всякий раз, когда вам нужно реализовать функцию «запроса» (это то, что обозначает Q в LINQ). Определить точный домен сложно, но он значительно упрощает различные задачи, связанные с извлечением данных из коллекций и манипулированием ими.

Чтобы уточнить, многие функции запросов были перенесены непосредственно в язык (точнее, в различные LINQ-разработчики), поэтому такие вещи, как агрегация, упорядочение, группировка, фильтрация, проекции, объединения (и многие другие), все обрабатываются для вы. Решения на основе LINQ, как правило, также намного короче, чем если бы вы реализовывали их «вручную», а также гораздо лучше сообщают о своих намерениях.

Простой пример, который часто помогает передать всю мощь LINQ, - это отображение содержимого каталога, сгруппированного по расширению. Выполните типичную императивную реализацию в своей голове - там будет много деталей реализации уже с самого начала. Возможно, мы будем использовать Dictionary<String, List<String>>для индексации файлов по расширению. Конечно, нам нужно проверить, существует ли ключ, создать список, добавить его и т. Д. Он может выглядеть примерно так:

Dictionary<string, List<string>> fileGroups = new Dictionary<string, List<string>>();

foreach (string file in Directory.GetFiles(Environment.CurrentDirectory))
{
    string extension = Path.GetExtension(file).ToLower();

    if (!fileGroups.ContainsKey(extension))
    {
        fileGroups[extension] = new List<string>();
    }

    fileGroups[extension].Add(file);
}

Рассмотрим эквивалент LINQ:

var query = from file in Directory.GetFiles(Environment.CurrentDirectory)
            group file by Path.GetExtension(file).ToLower();

Обратите внимание, что сам запрос состоит всего из 2 строк, что, безусловно, короче любого обязательного решения, которое мы могли бы предложить. Это также довольно читабельно; отношение сигнал / шум выше, чем при первом решении. Для тех, кто не знаком с LINQ, вы должны вывести результаты этого запроса следующим образом:

foreach (var fileGroup in query)
{
    Console.WriteLine(String.Format("*** Files with extension: {0}", group.Key));

    foreach (string file in fileGroup)
    {
        Console.WriteLine(file);
    }
}

В более сложных примерах различия обычно становятся еще более значительными (например, рассмотрите возможность группировки по нескольким полям). Подводя итог, можно сказать, что LINQ решает многие «повседневные» проблемы, связанные с запросами данных, часто короче и более информативно. Это требует умеренных затрат на изучение синтаксиса и технологий, но преимущества значительно перевешивают недостатки.


Вы классифицируете карту или складываете как "запросы"? Я не очень, но я думаю, что я мог видеть это возможно .. Я обычно думал бы о совокупности в результате вычисления, а не "запроса"
Джимми Хоффа

@JimmyHoffa Я в основном имею в виду применение вычислений к базовой коллекции, а не обязательно сами вычисления. Но в моей аналогии, вероятно, есть зияющие дыры, она должна быть иллюстративной, а не на 100% правильной.
Даниэль Б

@JimmyHoffa нет, но тогда я не уверен, что существует строгое определение того, с чего начинать запрос
jk.

0

Со временем были разработаны разные языки для различных типов источников данных, например, SQL для реляционных баз данных и XQuery для XML. Поэтому разработчикам приходилось изучать новый язык запросов для каждого типа источника данных или формата данных, который они должны поддерживать. LINQ упрощает эту ситуацию, предлагая согласованную модель для работы с данными в различных источниках данных и форматах. В запросе LINQ вы всегда работаете с объектами. для получения дополнительной информации посетите http://msdn.microsoft.com/en-us/library/bb397906.aspx


Именно LINQ - это API абстракции для работы с коллекциями. Некоторые важные преимущества: используя C #, вы получаете STATIC! Проверка ваших запросов и преобразований
AndreasScheinert
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.