Честно говоря, иногда это может быть ситуативным, когда вы начинаете использовать 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, используемое для проверки, если ID меньше 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 просто существует, потому что метод расширения where в порядке с методом, который принимает пользователя и целое число и возвращает логическое значение. Раздражает этот пример.
Теперь, если вы посмотрите на запрос 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)
Так что вы можете видеть, что иногда может быть проще использовать подход с использованием запросов.
Они компилируют то же и эквивалентны. Лично, я предпочитаю лямбду (расширение) методы для большинства вещей, только с помощью операторов (стандарт), если я делаю LINQ к SQL или иначе пытаюсь эмулировать SQL. Я нахожу, что методы лямбды текут лучше с кодом, тогда как операторы визуально недовольны.
Одно преимущество для использования методов расширения 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");
, По-моему, последний, с помощью основанный на методе запрос , читает лучше, когда у Вас есть пользовательские дополнительные методы.
Я предпочитаю дополнительный синтаксис метода, когда я использую методы Linq, которые не имеют никакого эквивалентного синтаксиса запроса, такого как FirstOrDefault () или другие как этот.