Лямбда против LINQ- «Выражение всегда ложно» - PullRequest
9 голосов
/ 22 июня 2011

У меня есть следующий код:

var thing = (from t in things
             where t.Type == 1 && t.IsActive
             select t).SingleOrDefault();

if (thing == null)
{
    // throw exception
}

things - это коллекция самопроверяющихся сущностей Entity Framework

Это хорошо работает, однако я хочу использовать вместо этого лямбда-выражение и изменило LINQ на это:

var thing = things.Select(t => t.Type == 1 && t.IsActive).SingleOrDefault();

Теперь Решарпер говорит мне Expression is always false для (thing == null).

Что я пропустил?

1 Ответ

15 голосов
/ 22 июня 2011

Требуется:

var thing = things.Where(t => t.Type == 1 && t.IsActive).SingleOrDefault();

Select выполняет проекцию (преобразование типа IEnumerable из IEnumerable<Thing> в IEnumerable<bool> со значениями true, если t.Type == 1 && t.IsActive == true, в противном случае false), то SingleOrDefault возвращает либо единственное bool в этой последовательности, либо значение по умолчанию bool, равное false, если последовательность пуста.Это никогда не может быть нулевым, поскольку bool не является ссылочным типом.

Where выполняет действие фильтрации (извлекает только те объекты, которые соответствуют заданному критерию - в этом случае выбираются только те, где Typeравно 1 и IsActive равно true), оставляя тип IEnumerable как IEnumerable<Thing>.Предполагая, что Thing является классом, SingleOrDefault вернет единственный элемент в последовательности или null.

В любом случае SingleOrDefault сгенерирует исключение, если последовательность содержит более одного элемента(что гораздо более вероятно в версии Select!).

...