Лямда выражение где VS FirstOrDefault - PullRequest
0 голосов
/ 09 ноября 2018

Я новичок в использовании lamda expressions и пытаюсь понять некоторые вещи. Я создал следующую часть кода, который возвращает путь к файлу журнала.

public static string GetLogFile()
{
    var fileTarget = LogManager.Configuration.AllTargets.Where(t=>t.Name == "LogName") as FileTarget;            
    return fileTarget == null ? string.Empty : fileTarget.FileName.Render(new LogEventInfo { Level = LogLevel.Info });
}

Моя проблема в том, что fileTarget пусто, когда я использую:

LogManager.Configuration.AllTargets.Where(t=>t.Name == "LogName")

Но если я изменю эту строку кода как

LogManager.Configuration.AllTargets.FirstOrDefault(t=>t.Name == "LogName")

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

Ответы [ 3 ]

0 голосов
/ 09 ноября 2018

Где на самом деле возвращает IEnumerable (intellisense сообщит вам об этом). Он не знает, сколько элементов может соответствовать вашему предикату. FirstOrDefault получит первый элемент или первый элемент, который соответствует вашему предикату. Если вы прошли один.

(Примечание. Предикат - это любая функция, которая принимает объект и возвращает логическое значение. Существует тип .Net с именем Predicate<T>, который представляет его)

Чтобы привести в порядок все, и вы можете сделать это, используя оператор OfType linq и операторы распространения и объединения нулей

public static string GetLogFile()
{
    var fileTarget = LogManager.Configuration.AllTargets.OfType<FileTarget>().FirstOrDefault(t=>t.Name == "LogName");            
    return fileTarget?.FileName.Render(new LogEventInfo { Level = LogLevel.Info }) ?? string.Empty;
}
0 голосов
/ 09 ноября 2018

Проще говоря,

Where предоставит вам Enumerable. Не будет нулевым Пусто, если в предикате нет совпадений. FirstOrDefault даст вам объект. Нет, если совпадения нет.

Исходя из вашего кода, он должен выдать ошибку компиляции, говорящую, что он не может конвертировать из IEnumerable в FileTarget.

0 голосов
/ 09 ноября 2018

В вашем случае Where возвращает IEnumerable (просто список) объекта FileTarget. Затем вы приведете этот список к FileTarget. Вот почему это ноль.

Но FirstOrDefault возвращает объект или null и может быть преобразован в ваш класс FileTarget. Вот почему это работает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...