Синтаксис методов расширения и синтаксиса запросов

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

var query = from p in Products
    where p.Name.Contains("foo")
    orderby c.Name
    select p;

// or with extension methods:
var query = Products
    .Where(p => p.Name.Contains("foo"))
    .OrderBy(p => p.Name);

Они очень похожи, а второй пример немного более короткий, но, возможно, менее выразительный, если вы не знаете, что делает the = > .

Помимо написания сложного кода, существуют ли другие преимущества использования методов расширения в отличие от синтаксиса LINQ?

Ответ 1

Честно говоря, иногда это может быть ситуативным, когда вы начинаете использовать Funcs и Actions. Скажем, вы используете эти три функции:

  Func<DataClasses.User, String> userName = user => user.UserName;
  Func<DataClasses.User, Boolean> userIDOverTen = user => user.UserID < 10;
  Func<DataClasses.User, Boolean> userIDUnderTen = user => user.UserID > 10;

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

ПРИМЕЧАНИЕ. Это глупый пример, но он работает.

  var userList = 
    from user in userList
    where userIDOverTen(user)
    select userName;

Против

  var otherList =
    userList
    .Where(IDIsBelowNumber)
    .Select(userName)

В этом примере второй немного менее подробный, так как метод расширения может полностью использовать Func, но выражение Linq не может, поскольку оно выглядит только для логического, а не для Func, возвращающего логическое значение. Однако здесь лучше использовать язык выражений. Скажем, у вас уже есть метод, который принимает не только пользователя:

  private Boolean IDIsBelowNumber(DataClasses.User user, 
          Int32 someNumber, Boolean doSomething)
  {
    return user.UserID < someNumber;
  }

Примечание: doSomething существует только из-за того, что метод расширения в порядке с методом, который принимает пользователя и целое число и возвращает значение boolean. Вид раздражает для этого примера.

Теперь, если вы посмотрите на запрос Linq:

  var completeList =
     from user in userList
     where IDIsBelowNumber(user, 10, true)
     select userName;
Ты хорош для этого. Теперь метод расширения:
  var otherList =
    userList
    .Where(IDIsBelowNumber????)
    .Select(userName)

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

   private Func<DataClasses.User, Boolean> IDIsBelowNumberFunc(Int32 number)
   {
      return user => IDIsBelowNumber(user, number, true);
   }

И затем подключите его:

  var otherList =
     userList
     .Where(IDIsBelowNumberFunc(10))
     .Select(userName)

Таким образом, вы можете видеть, иногда просто может быть проще использовать подход запроса.

Ответ 2

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

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

Пример

Я использую собственный метод расширения, называемый Into, который просто берет строку:

Пример с запросом

var query = (from p in Products
    where p.Name.Contains("foo")
    orderby c.Name
    select p).Into("MyTable");

Пример с методами расширения

var query = Products
                   .Where(p => p.Name.Contains("foo"))
                   .OrderBy(p => p.Name)
                   .Into("MyTable");

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

Ответ 3

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

В основном это личный вкус, но в синтаксисе запроса (метод понимания) не все операторы доступны, как было сказано ранее.

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

Только мои два цента.

Поскольку я не могу комментировать все же, я хочу сделать это здесь, чтобы ответить на Инструмент программирования: Зачем делать совершенно новый метод для последнего примера? Не можете ли вы просто использовать:

.Where(user => IDIsBelowNumber(user, 10, true))

Ответ 4

Они компилируют то же самое и эквивалентны. Лично я предпочитаю методы лямбда (расширения) для большинства вещей, только используя операторы (стандартные), если я делаю LINQ to SQL или иным образом пытаюсь эмулировать SQL. Я нахожу, что методы лямбда лучше работают с кодом, тогда как операторы визуально отвлекают.

Ответ 5

Я предпочитаю синтаксис метода расширения, когда я использую методы Linq, у которых нет синтаксиса синтаксиса запроса, например FirstOrDefault() или других подобных.

Ответ 6

Мне нравится использовать синтаксис запроса, когда это действительно запрос, т.е. ленивое выражение, которое оценивается по требованию.

Метод, который выглядит как обычные вызовы методов (синтаксис метода или синтаксис лямбда), не выглядит ленивым, поэтому я использую это как соглашение. Например,

var query = from p in Products
            where p.Name.Contains("foo")
            orderby p.Name
            select p;

var result = query.ToList(); //extension method syntax

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

var nonQuery = Products.Where(p => p.Name.Contains("foo"))
                       .OrderBy(p => p.Name)
                       .ToList();

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