Для якого проблемного домену створено LINQ?


12

Кожен раз, коли я бачу запитання, розміщені на "Переповнення стека" на C #, я бачу щонайменше один-два відповіді, які вирішують проблему з LINQ. Зазвичай люди з дуже високою репутацією, здається, використовують LINQ як профі.

Отже, моє запитання полягає в тому, для якої проблемної області слід використовувати LINQ?

Також на бічних зауваженнях: Чи є якісь цілі, в яких слід уникати цього? Чи впливає розмір набору даних на ефективність запитів LINQ?




1
LINQ призначений для запиту графіків об'єктів. Це мовний інтегрований запит - він дозволяє запитувати та маніпулювати колекціями.
Oded

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

1
Linq - декларативний. Ви заявляєте "що" ви хочете, не вказуючи "як" це робиться. Для 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 або більше) або програмного ейлера .


Можливо, мені доведеться зараз видалити це питання. Модератор прокоментував, що це не підходить для громади. Якщо ви відчуваєте інше, будь ласка, скажіть мені.
користувач1816120

1
Я додам, що якщо ви перезаписуєте його на LINQ, а оригінал все ще читається, збережіть оригінал та видаліть версію LINQ. Іноді LINQ просто нічого не додає.
svick

@svick теоретично так, я не впевнений, що можу придумати будь-які приклади цього;)
jk.

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

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

1

Щоб відповісти на відредаговане запитання: коротше кажучи, корисно використовувати LINQ, коли вам доведеться реалізувати функцію "запиту" (саме для цього і відповідає Q у LINQ). Визначити точний домен складно, але це значно спрощує різноманітні завдання, пов’язані з вилученням та маніпулюванням даними з колекцій.

Щоб трохи уточнити, багато функцій запитів було передано безпосередньо мовою (а точніше, різними LINQ-реалізаторами), тому такі речі, як агрегація, упорядкування, групування, фільтрація, проекції, з'єднання (та багато іншого), обробляються ви. Рішення на основі LINQ, як правило, набагато коротші, ніж якби ви їх реалізували "вручну", а також повідомляли про їх наміри набагато краще.

Простий приклад, який часто допомагає передати потужність LINQ - це відображення вмісту каталогу, згрупованого за розширенням. Пробіжіть типову імперативну реалізацію в голові - буде багато деталей щодо впровадження вже на самому початку. Можливо, ми будемо використовувати a 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.