Comments 43
Очевидно, второй.
Какие-то детские задачки :S
Тем не менее, я почему-то очень часто вижу именно первый вариант в чужом коде...
Программисты выучивают
FirstOrDefault()
и используют его везде, даже где более уместны First()
или ещё лучше Single()
.Используют
.Where(predicate).Count()
вместо .Count(predicate)
, или какие-то запутанные условия в OrderBy
вместо ThenBy
, не используют Cast()
и GroupBy()
Используют .Where(predicate).Count()
вместо .Count(predicate)
где то я читал, что первый вариант оптимальней
Каким образом вариант, создающий лишнюю обертку, может быть оптимальнее?
А вот про именно специфичные для отладки/инвестигирования кейсы было интересно почитать, даже сходу ничего не приходит в голову.
// вариант 3
switch (thing)
{
case Foo foo:
foo.DoSomething();
.....
}
Из разряда «из двух неправильных вариантов выберите менее неправильный»
Предпочтительнее тот вариант, который больше удовлетворяет цель. Если мы, например, для того, чтобы отобразить на главной странице незначительную ерунду используем .Firts() и весь веб падает в случае отсутствии этой ерунды, то аргумент "зато проще отлаживать" явно не катит.
В приведенном примере, в случае отсутствия элемента в кол-ции, FirstOrDefault() все равно не спасает.
Тогда уж его хотя бы нужно переписать:
collection.FirstOrDefault()?.DoSomething();
Так что вариант 1 просто вносит дополнительную ненужную проверку и портит колстек в случае ошибки.
Глупость какая-то. В обоих случаях первый вариант является просто плохим кодом. Когда пишешь thing as Foo
или collection.FirstOrDefault()
, нужно учесть вероятность получения null
— проверить результат на null
, использовать оператор ?.
и т. п.
Второй вариант допустим, когда уверен, что в нормальных условиях этот код сработает — что thing
— это действительно всегда Foo
, и что в коллекции обязательно есть как минимум один элемент.
Вопрос выбора между равнозначными вариантами не стоит.
Представим себе, что ровно тот же текст, байт в байт, только без картинко-текста (пора вводить в язык новое слово — pictext, оно же пиктекст) с логотипом Майкрософт, Вася Пупкин написал в песочницу. Вопрос: пустят ли Васю Пупкина на Хабр?
Ну, нельзя так… а проще, конечно, второй. Если что. Это можно ответить даже не зная C#.
Хотя здесь все-таки не NullReferenceException, а ArgumentNullException, First будет как минимум более выразительным.
Смотря для чего лучше.
С точки зрения отладки, второй лучше — если мы забыли проверку, он вывалится в одном месте, а не в рандомном, где мы используем результат. Но с точки зрения производительности лучше просто проверить результат на null.
var item = collection.FirstOrDefault().DoSomething();
if(item == null)
{
// обработать
}
Еще никогда у меня не было выбора между двумя вариантами кода, вариантов всегда очень много. Пока есть дженерики + экстеншны или наследование первые 2 варианта примера никогда не придется писать.
Оба варианта ниже функционально эквивалентны.
В общем случае нет.
Если нет разницы...
Странно, но по мне разница есть. И она описывает соглашение того, что мы ожидаем получить в thing.
Использую оба варинта:
- вариант 1 — если в thing может быть произвольного типа.
- вариант 2 — если в thing обязан реализовать контракт типа Foo
И да, проверка на null — для обоих результатов обязательна, с выбрасыванием "вменяемого" исключения.
Если нет разницы между двумя вариантами кода, выбирай тот, который проще отладить