Ответ
Оба метода возвращают первый элемент последовательности, но их поведение при пустой коллекции или отсутствии совпадений принципиально различается.
First()
- Возвращает первый элемент, удовлетворяющий необязательному предикату.
- Если результат пуст (последовательность пуста или ни один элемент не соответствует условию), метод выбрасывает
InvalidOperationException. - Используйте, когда наличие элемента гарантировано логикой программы. Исключение в этом случае — это fail-fast механизм, указывающий на ошибку в данных или логике.
FirstOrDefault()
- Возвращает первый элемент или значение по умолчанию для типа элемента, если последовательность пуста или нет совпадений.
- Для ссылочных типов —
null. - Для числовых типов значений —
0. - Для
bool—false. - Для
DateTime—DateTime.MinValue.
- Для ссылочных типов —
- Используйте, когда отсутствие элемента является нормальным, допустимым сценарием, и вы готовы обработать значение по умолчанию.
Практические примеры
var numbers = new List<int> { 1, 2, 3, 4, 5 };
var emptyList = new List<int>();
// First — когда элемент должен быть
int firstNumber = numbers.First(); // 1
int firstEven = numbers.First(n => n % 2 == 0); // 2
// int willThrow = emptyList.First(); // InvalidOperationException!
// FirstOrDefault — когда элемент может отсутствовать
int safeFirst = emptyList.FirstOrDefault(); // 0 (значение по умолчанию для int)
int firstGreaterThanTen = numbers.FirstOrDefault(n => n > 10); // 0 (нет совпадений)
// Работа со ссылочными типами
var users = new List<User>();
User foundUser = users.FirstOrDefault(u => u.Id == 123); // null
if (foundUser != null) {
// Обрабатываем найденного пользователя
}
Рекомендация: Выбор метода — это вопрос семантики. First выражает требование, FirstOrDefault — допущение. Использование First там, где элемент может отсутствовать, маскирует ошибки.
Ответ 18+ 🔞
А, слушай, вот эта тема с First и FirstOrDefault — она вечно всех новичков в ступор вгоняет, а на деле всё проще простого, если на пальцах объяснить.
Представь себе очередь в столовую. First() — это как самый голодный мужик в начале очереди, который точно уверен, что плов сегодня есть. Он подходит к раздаче, а там — пусто. Что он делает? Правильно, он орет на всю столовую: «БЛЯДЬ, ГДЕ ЕДА?!» — это и есть твой InvalidOperationException. Используешь First(), только если ты на 146% уверен, что в коллекции что-то есть. Если нет — получишь по ебалу исключением, и правильно сделают.
А FirstOrDefault() — это я. Я подхожу по-тихому, смотрю: а плова-то и нет. Ну хуй с ним, пошел чай пить с булкой. То есть, если ничего нет, метод не орет, а просто возвращает значение по умолчанию и идет по своим делам. Для чисел это 0, для объектов — null, для bool — false. Используешь, когда отсутствие элемента — это нормальная рабочая ситуация, а не конец света.
Вот смотри на примерах, тут всё сразу встанет на свои места:
// Допустим, у нас список
var numbers = new List<int> { 1, 2, 3, 4, 5 };
var emptyList = new List<int>(); // А это пустой список, пиздец
// First — когда ты уверен, как в Бога
int firstNumber = numbers.First(); // 1, всё ок
int firstEven = numbers.First(n => n % 2 == 0); // 2, тоже ок
// А вот это уже пиздец:
// int willThrow = emptyList.First(); // Вылетит InvalidOperationException, потому что там нихуя нет!
// FirstOrDefault — когда похуй, найдётся — хорошо, не найдётся — иди нахуй
int safeFirst = emptyList.FirstOrDefault(); // Вернёт 0 (дефолт для int), тишина, анархия
int firstGreaterThanTen = numbers.FirstOrDefault(n => n > 10); // Тоже 0, потому что таких чисел нет
// С объектами та же история
var users = new List<User>(); // Пустой список пользователей
User foundUser = users.FirstOrDefault(u => u.Id == 123); // Вернёт null
if (foundUser != null) {
// Ну если не null, то можно работать
// А если null — ну значит, пользователя нет, и хуй с ним
}
Короче, суть в чём: First — это когда элемент должен быть, а его отсутствие — это пиздец и ошибка в логике. FirstOrDefault — это когда элемент может быть, а может и не быть, и тебе надо это корректно обработать. Выбирай по ситуации, а не тыкай наугад, а то потом будешь исключения ловить там, где их быть не должно, ебать.