логическое короткое замыкание и лямбды


У меня есть следующее лямбда-выражение:

response = allDescendants
        .Where(n =>
        n.Caption.Contains(query) ||
        n.Identifier.ToString().Contains(query) ||
        n.Type.ToString().Contains(query) ||
        n.Path.Contains(query) ||
        n.Description.Contains(query) ||
        (n.KeyWords != null && n.KeyWords.Any(kw => kw.Contains(query))) ||
        n.SubType.Contains(query) ||
        n.GroupingBy.Contains(query)
        ).ToList();

В определении класса поле ключевого слова имеет значение null:

private string[] keyWords = null;
public string[] KeyWords
{
    get { return keyWords; }
    set { keyWords = value; }
}

Строка (n.KeyWords != null && n.KeyWords.Any(kw => kw.Contains(query))) выбрасывает исключение NullReferenceException, потому что поле ключевого слова равно null, но у меня сложилось впечатление, что поскольку проверка на null произошла до лямбды, все выражение должно замкнуться на false. Это что-то конкретное, связанное с лямбдой, или что-то еще, чего я не понимаю?

Правка:

Я нашел виновник, это был конструктор, который устанавливает массив string в string[1] вместо null.

2 2

2 ответа:

Отладчик просто помечает всю эту строку. n.KeyWords не было нулевым, так как, действительно, && короткие замыкания. (Или, что свойство KeyWords возвращает ненулевое значение в первый раз и нулевое значение во второй раз, когда оно вызывается!)

Посмотрите на стек вызовов, чтобы увидеть, в каком методе на самом деле произошел сбой. Лямбда будет сверху, и use может использовать отладчик для проверки значения kw, которое будет равно null.

Как и все в комментариях, я искал путь кода, который устанавливает элементы моего массива в null вместо всего массива, и нашел его. Теперь он устанавливает для всего массива значение null, и код работает так, как задумано.