FirstOrDefault () прочь LINQ по сравнению с FirstOrDefault () с Лямбдой?

Мне немного любопытно, относительно которого считается "лучшей практикой" когда дело доходит до FirstOrDefault.

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

Какой из них является "лучшим кодом"? и почему?

var foos = GetMyEnumerableFoos();

var foo1 = (from f in foos
     where f.Bar == "spider monkey"
     select f).FirstOrDefault();

/* OR */

var foo2 = foos.FirstOrDefault(f => f.Bar == "spider monkey");

Я склоняюсь к последнему как IMO, он делает для более чистого кода. Но мне любопытно относительно того, более ли технические "кишки" того, что продолжается, там эффективны другой путь. Это изменяется при использовании различных типов IEnumerables? как DataTables или массивы строк или объекты LINQ?

========= редактирование ==========

Должность принимающего Jon Skeet корректна, я пошел, изучив Отражатель для наблюдения что, Где и FirstOrDefault похожи и здесь то, что я придумал:

В случае foos. Где (f => f. Панель == "обезьяна паука").FirstOrDefault ()

public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
{
    if (source == null)
    {
        throw Error.ArgumentNull("source");
    }
    if (predicate == null)
    {
        throw Error.ArgumentNull("predicate");
    }
    if (source is Iterator<TSource>)
    {
        return ((Iterator<TSource>) source).Where(predicate);
    }
    if (source is TSource[])
    {
        return new WhereArrayIterator<TSource>((TSource[]) source, predicate);
    }
    if (source is List<TSource>)
    {
        return new WhereListIterator<TSource>((List<TSource>) source, predicate);
    }
    return new WhereEnumerableIterator<TSource>(source, predicate);
}

который питался бы в:

public static TSource FirstOrDefault<TSource>(this IEnumerable<TSource> source)
{
    if (source == null)
    {
        throw Error.ArgumentNull("source");
    }
    IList<TSource> list = source as IList<TSource>;
    if (list != null)
    {
        if (list.Count > 0)
        {
            return list[0];
        }
    }
    else
    {
        using (IEnumerator<TSource> enumerator = source.GetEnumerator())
        {
            if (enumerator.MoveNext())
            {
                return enumerator.Current;
            }
        }
    }
    return default(TSource);
}

В случае foos. FirstOrDefault (f => f. Панель == "обезьяна паука");

public static TSource FirstOrDefault<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
{
    if (source == null)
    {
        throw Error.ArgumentNull("source");
    }
    if (predicate == null)
    {
        throw Error.ArgumentNull("predicate");
    }
    foreach (TSource local in source)
    {
        if (predicate(local))
        {
            return local;
        }
    }
    return default(TSource);
}

Рассмотрение этого все еще оставляет меня немного смущенным, там была бы эффективность, добавленная при помощи надлежащего итератора для определенных типов объектов? Или действительно ли более эффективно пропустить все это и только запустить цикличное выполнение через и тестирование? Мой пищеварительный тракт снова говорит мне, что это - последний.

14
задан Ben Lesh 27 January 2010 в 16:01
поделиться

3 ответа

Ну, часть «выбора» будет удалена компилятором в любом случае, поэтому вы действительно сравниваете:

foo.Where(f => f.Bar == "spider monkey")
   .FirstOrDefault()

против

foo.FirstOrDefault(f => f.Bar == "spider monkey")

Я сомневаюсь, что это сделает какой-либо Разница в зависимости от эффективности в пределах LINQ до объектов в любом случае. Я бы лично использовал последнюю версию самого себя ... Если я не хотел повторно использовать фильтрующую часть запроса в другом месте.

18
ответ дан 1 December 2019 в 12:52
поделиться
  1. Безопасно хранить в одном конкретном часовом поясе, в идеале в формате UTC
  2. Если вы храните время с указанием даты, вы в безопасности в режиме DST.
  3. Предлагая использовать веб-сервис для поиска разницы во времени.
-121--3311451-

Я предпочитаю последнее просто потому, что оно более лаконичное.

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

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

4
ответ дан 1 December 2019 в 12:52
поделиться

Вторая версия будет намного эффективнее.

Первая версия

var foo1 = (from f in foos
     where f.Bar == "spider monkey"
     select f).FirstOrDefault();

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

Вторая версия

var foo2 = foos.FirstOrDefault(f => f.Bar == "spider monkey");

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

-1
ответ дан 1 December 2019 в 12:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: