Когда использовать .First и когда использовать .FirstOrDefault с LINQ?

Я искал вокруг и не нашел четкого ответа относительно того, когда вы хотите использовать .Firstи когда вы хотите использовать .FirstOrDefaultс LINQ.

  • Когда бы вы хотели использовать .First? Только когда вы захотите перехватить исключение, если результаты не возвращены?

    var result = List.Where(x => x == "foo").First();
  • И когда бы вы хотели использовать .FirstOrDefault? Когда вы всегда хотите тип по умолчанию, если нет результата?

    var result = List.Where(x => x == "foo").FirstOrDefault();
  • И в этом отношении, что относительно Take?

    var result = List.Where(x => x == "foo").Take(1);
21.06.2009 19:15:29
.Firstи .FirstOrDefaultоба принимают предикаты в качестве аргументов, поэтому var result = List.Where(x => x == "foo").First();могут быть переписаны какvar result = List.First(x => x == "foo");
Rian Schmits 22.06.2011 15:39:08
Не забудьте рассмотреть Singleи SingleOrDefault. Я ненавижу, когда люди используют, Firstкогда они действительно имеют в виду Single; )
BartoszKP 22.09.2013 00:33:14
Single или SingleOrDefault будут генерировать исключение, если возвращено более одного элемента! Я думаю, что FirstOrDefault лучше в большинстве распространенных случаев!
Eric Draven 31.03.2016 13:33:43
Дело в том, что когда вы ожидаете одного результата, вы должны сказать об этом, а исключение означает, что ваша логика не удалась.
NetMage 24.10.2016 20:57:53
Также учтите, что использование .FirstOrDefault()всегда дает вам возможность создать более значимое исключение. Если выдается исключение последовательности и более одного .First()в методе, может быть трудно определить, какой оператор является проблемой.
StingyJack 6.11.2017 14:00:33
14 ОТВЕТОВ
РЕШЕНИЕ

Я бы использовал, First()когда знаю или ожидаю, что в последовательности будет хотя бы один элемент. Другими словами, когда это исключительный случай, последовательность пуста.

Используйте, FirstOrDefault()когда вы знаете, что вам нужно будет проверить, был ли элемент или нет. Другими словами, когда допустимо, чтобы последовательность была пустой. Вы не должны полагаться на обработку исключений для проверки. (Это плохая практика и может повредить производительность).

Наконец, разница между First()и Take(1)заключается в том, что First()возвращает сам элемент, а Take(1)возвращает последовательность элементов, которая содержит ровно один элемент.

804
25.02.2019 19:52:12
@driis - я полагаю, что мы можем использовать мантру об исключительных правилах исключений при выборе между First и FirstOrDefault. Спасибо за четкий ответ.
Metro Smurf 21.06.2009 21:21:43
Единственное, что я хотел бы добавить, это то, что если значение по умолчанию для выбранного вами типа может быть допустимым значением, например, ваш результат может быть значением int 0, то обработка исключения, кажется, лучший способ справиться с этим. ,
PeterBelm 19.04.2012 08:59:33
Поцарапав это, я нашел гораздо более хороший способ сделать это, используя: DefaultIfEmpty (-1) .First ()
PeterBelm 19.04.2012 09:03:53
Take не возвращает ровно один элемент, оно возвращает не более одного элемента (если вы, конечно, укажите 1). Он также может вернуть 0 элементов, если последовательность изначально пуста.
SPIRiT_1984 16.05.2012 07:12:31
@RoyiNamir, да, в контексте вопроса, где взять параметр, равный 1. Я также отметил, что в скобках сразу после этого предложения.
driis 21.01.2015 17:48:42

.First()выдаст исключение, если нет строки для возврата, а вместо этого .FirstOrDefault()вернет значение по умолчанию ( NULLдля всех ссылочных типов).

Так что, если вы готовы и готовы обработать возможное исключение, .First()это нормально. Если вы != nullвсе равно предпочитаете проверять возвращаемое значение , тогда .FirstOrDefault()это ваш лучший выбор.

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

114
26.07.2019 09:31:37

.Firstвыдаст исключение, когда нет результатов. .FirstOrDefaultне будет, он просто вернет либо ноль (ссылочные типы), либо значение по умолчанию для типа значения. (например, как 0для int.) Вопрос здесь не в том, когда вам нужен тип по умолчанию, а в следующем: готовы ли вы обрабатывать исключение или обрабатывать значение по умолчанию? Поскольку исключения должны быть исключительными, FirstOrDefaultэто предпочтительнее, когда вы не уверены, собираетесь ли вы получить результаты из своего запроса. Когда логически данные должны быть там, обработка исключений может быть рассмотрена.

Skip()и Take()обычно используются при настройке подкачки в результатах. (Например, показ первых 10 результатов и следующих 10 на следующей странице и т. Д.)

Надеюсь это поможет.

268
21.11.2016 15:20:37
@Jeroen - хорошее замечание о лучших вариантах использования Skip / Take.
Metro Smurf 21.06.2009 21:11:29
+1 за объяснение, которое .FirstOrDefaultбудет возвращать ноль для ссылочных типов. Я был озадачен тем, каким будет объект «по умолчанию». Этот ответ прояснил это.
Mike Taverne 4.10.2018 17:39:50

Прежде всего, Takeэто совершенно другой метод. Возвращает, IEnumerable<T>а не один T, так что нет.

Между Firstи FirstOrDefault, вы должны использовать, Firstкогда вы уверены, что элемент существует, а если нет, то есть ошибка.

Между прочим, если ваша последовательность содержит default(T)элементы (например null), и вам нужно различать, является ли элемент пустым, а первым - быть null, вы не можете его использовать FirstOrDefault.

20
21.06.2009 19:23:55
@Mehrdad - замечательные моменты, re: .First возвращает IEnumerable и когда не следует использовать FirstOrDefault.
Metro Smurf 21.06.2009 21:09:57

Я нашел веб-сайт, который должен объяснить необходимость использования FirstOrDefault
http://thepursuitofalife.com/the-linq-firstordefault-method-and-null-resultsets/
Если в запросе нет результатов, и вы хотите позвонить Сначала () или Single (), чтобы получить одну строку ... Вы получите исключение «Последовательность не содержит элементов».

Отказ от ответственности: я никогда не использовал LINQ, поэтому мои извинения, если это далеко от истины.

3
21.06.2009 19:24:55
someList.First(); // exception if collection is empty.
someList.FirstOrDefault(); // first item or default(Type)

Какой использовать? Это должно решаться бизнес-логикой, а не боязнью отказа / сбоя программы.

Например, если бизнес-логика говорит, что мы не можем иметь нулевые транзакции в любой рабочий день (просто предположим). Тогда вам не следует пытаться справиться с этим сценарием с помощью какого-то умного программирования. Я всегда буду использовать First () над такой коллекцией, и позволить программе завершиться ошибкой, если что-то еще испортит бизнес-логику.

Код:

var transactionsOnWorkingDay = GetTransactionOnLatestWorkingDay();
var justNeedOneToProcess = transactionsOnWorkingDay.First(): //Not FirstOrDefault()

Я хотел бы видеть другие комментарии по этому поводу.

2
21.06.2009 22:25:08
Значением по умолчанию для ссылочного и обнуляемого типов является null.
dsa 20.05.2013 13:42:12
Быстро завершиться неудачей - это хорошо - однако для описанного вами сценария я бы предпочел сначала посмотреть, не получится ли это, поймать исключение и затем вернуть значимую ошибку. Как catch (InvalidOperationException e) {throw new InvalidOperationException ("Не может иметь ноль транзакций за день!", E)}; Но да, использование по умолчанию, чтобы избежать реальной проблемы бизнес-логики, очень плохо.
Mathieson 15.09.2014 15:08:56

Хорошо, позвольте мне дать два моих цента. First / Firstordefault для, когда вы используете второй конструктор. Я не буду объяснять, что это такое, но это когда вы потенциально всегда используете один, потому что вы не хотите вызывать исключение.

person = tmp.FirstOrDefault(new Func<Person, bool>((p) =>
{
    return string.IsNullOrEmpty(p.Relationship);
}));
1
3.12.2011 22:02:40
Не совсем. Первый конструктор широко используется, когда вам нужно извлечь только один элемент или избежать ошибки компиляции при присваивании результата значению, которое не является массивом, и вы уверены, что запрос возвращает ровно один результат. Хотя может показаться, что использовать второй конструктор быстрее, чем использование дополнительного .Where () (поскольку, по вашему мнению, LINQ прекращает оценку элементов в списке после нахождения первого), он всегда останавливается на первом элементе
usr-local-ΕΨΗΕΛΩΝ 8.06.2012 18:56:26

Первый:

  • Возвращает первый элемент последовательности
  • Выдает исключение: в результате нет элементов
  • Используйте когда: когда ожидается более 1 элемента, и вы хотите только первый

FirstOrDefault:

  • Возвращает первый элемент последовательности или значение по умолчанию, если элемент не найден
  • Выдает исключение: только если источник нулевой
  • Используйте когда: когда ожидается более 1 элемента, и вы хотите только первый. Также вполне возможно, что результат будет пустым

От: http://www.technicaloverload.com/linq-single-vs-singleordefault-vs-first-vs-firstordefault/

15
4.04.2013 14:29:46

Первый()

  1. Возвращает первый элемент последовательности.
  2. Выдает ошибку, когда в результате отсутствует элемент или источник равен нулю.
  3. Вы должны использовать его, если ожидается более одного элемента, и вы хотите только первый элемент.

FirstOrDefault ()

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

У нас есть таблица UserInfos, в которой есть несколько записей, как показано ниже. На основе этой таблицы ниже я создал пример ...

Таблица пользовательских данных

Как использовать First ()

var result = dc.UserInfos.First(x => x.ID == 1);

Существует только одна запись, в которой идентификатор == 1. Должен вернуть
идентификатор этой записи : 1 Имя: Маниш Фамилия: Дубей E-mail: xyz@xyz.com

var result = dc.UserInfos.First(x => x.FName == "Rahul");   

Есть несколько записей, где FName == "Rahul". Первая запись должна быть возвращена.
ID: 7 Имя: Рахул Фамилия: Шарма Электронная почта: xyz1@xyz.com

var result = dc.UserInfos.First(x => x.ID ==13);

Нет записи с ID == 13. Должна возникнуть ошибка.
InvalidOperationException: последовательность не содержит элементов

Как использовать FirstOrDefault ()

var result = dc.UserInfos.FirstOrDefault(x => x.ID == 1);

Существует только одна запись, в которой идентификатор == 1. Должен вернуть
идентификатор этой записи : 1 Имя: Маниш Фамилия: Дубей E-mail: xyz@xyz.com

var result = dc.UserInfos.FirstOrDefault(x => x.FName == "Rahul");

Есть несколько записей, где FName == "Rahul". Первая запись должна быть возвращена.
ID: 7 Имя: Рахул Фамилия: Шарма Электронная почта: xyz1@xyz.com

var result = dc.UserInfos.FirstOrDefault(x => x.ID ==13);

Нет записи с идентификатором == 13. Возвращаемое значение равно нулю

Надеюсь, это поможет вам понять, когда использовать First()или FirstOrDefault().

66
26.08.2016 12:45:16
На мой взгляд, утверждение «ошибка должна произойти». под третьим FirstOrDefault () - пример вводит в заблуждение.
Jannik 28.09.2015 07:55:24
Здравствуйте, вы хорошо объясните, но я немного запутался, когда происходит получение данных из соединения, и когда идентификатор не существовал в таблице внешних ключей в то время, какой из них используется? В настоящее время я использую First (), но после прочтения вашего ответа я понятия не имею. Пожалуйста, помогите
Brijesh Mavani 23.10.2018 06:24:56

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

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

Вот почему я всегда использую, FirstOrDefault()хотя я знаю, что нулевая запись представляет собой исключительную ситуацию.

var customer = context.Customers.FirstOrDefault(i => i.Id == customerId);
if (customer == null)
{
   throw new Exception(string.Format("Can't find customer {0}.", customerId));
}
10
17.09.2014 00:57:54

Этот тип функции принадлежит элементным операторам. Некоторые полезные операторы элементов определены ниже.

  1. Во-первых / FirstOrDefault
  2. Последняя / LastOrDefault
  3. Одноместный / SingleOrDefault

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

  List<int> items = new List<int>() { 8, 5, 2, 4, 2, 6, 9, 2, 10 };

Оператор First () возвращает первый элемент последовательности после выполнения условия. Если элемент не найден, он выдаст исключение.

int result = items.Where (item => item == 2) .First ();

Оператор FirstOrDefault () возвращает первый элемент последовательности после выполнения условия. Если элемент не найден, он вернет значение по умолчанию этого типа.

int result1 = items.Where (item => item == 2) .FirstOrDefault ();

4
29.08.2018 05:06:32
хорошо объяснено на простом для понимания примере.
Arslan Bhatti 17.01.2019 12:08:11

Первый()

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

FirstOrDefault ()

FirstOrDefault () аналогичен First () за исключением того, что если ни один элемент не соответствует указанному условию, он возвращает значение по умолчанию базового типа универсальной коллекции. Он не выдает InvalidOperationException, если элемент не найден. Но коллекция элемента или последовательности равна нулю, чем исключение.

5
21.09.2016 10:40:00
Здравствуйте, вы хорошо объясните, но я немного запутался, когда происходит получение данных из соединения, и когда идентификатор не существовал в таблице внешних ключей в то время, какой из них используется? В настоящее время я использую First (), но после прочтения вашего ответа я понятия не имею. Пожалуйста, помогите
Brijesh Mavani 23.10.2018 06:24:47

У linq много способов реализовать один простой запрос к коллекциям, просто мы пишем объединения в sql, фильтр может применяться первым или последним в зависимости от необходимости и необходимости.

Вот пример, где мы можем найти элемент с идентификатором в коллекции. Чтобы добавить больше к этому, методы First, в FirstOrDefaultидеале, должны возвращать то же самое, когда в коллекции есть хотя бы одна запись. Если, однако, коллекция может быть пустой. затем Firstвернет исключение, но FirstOrDefaultвернет nullили по умолчанию. Например, intвернет 0. Таким образом, использование такового хотя и считается личным предпочтением, но его лучше использовать, FirstOrDefaultчтобы избежать обработки исключений. вот пример, где мы запускаем коллекцию списка транзакций

-6
24.05.2017 15:03:28

Другие очень хорошо описали разницу между First()и FirstOrDefault(). Я хочу сделать еще один шаг в интерпретации семантики этих методов. По моему мнению, FirstOrDefaultэто слишком злоупотребляют. В большинстве случаев, когда вы фильтруете данные, вы можете ожидать либо возврата коллекции элементов, соответствующих логическому условию, либо одного уникального элемента по его уникальному идентификатору, например, пользователя, книги, публикации и т. Д. почему мы можем даже сказать, что FirstOrDefault()это запах кода не потому, что с ним что-то не так, а потому, что он используется слишком часто. Этот пост в блоге исследует тему в деталях. ИМО в большинстве случаевSingleOrDefault() это гораздо лучшая альтернатива, поэтому следите за этой ошибкой и убедитесь, что вы используете наиболее подходящий метод, который четко отражает ваш контракт и ожидания.

0
28.02.2020 16:42:53