Итак, я столкнулся с ситуацией сегодня, когда какой-то производственный код терпел неудачу именно потому, что метод, выполненный точно как задокументированный в MSDN. Мне стыдно за то, что я не читал документацию. Тем не менее, я по-прежнему раскалываю голову о том, почему он ведет себя таким образом, даже если "по дизайну", поскольку это поведение совершенно противоположно тому, что я ожидал (и другим, известным поведением), и поэтому, по-видимому, нарушает принцип наименее неожиданным.
Метод All()
позволяет вам предоставить предикат (например, выражение лямбда) для тестирования IQueryable
, возвращая логическое значение, указывающее, соответствуют ли все члены коллекции тесту. Все идет нормально. Здесь, где это становится странным. All()
также возвращает true
, если коллекция пуста. Это кажется мне полностью обратным, по следующим причинам:
- Если коллекция пуста, такой тест, в лучшем случае, undefined. Если моя подъездная дорога пуста, я не могу утверждать, что все автомобили, припаркованные там, красные. При таком поведении на пустой дороге все припаркованные автомобили есть красная И синяя И шахматная доска - все эти выражения вернутся к истине.
- Для тех, кто знаком с понятием SQL, что NULL!= NULL, это неожиданное поведение.
- Метод
Any()
работает так, как ожидалось, и (правильно) возвращает false, потому что у него нет элементов, соответствующих предикату.
Итак, мой вопрос: почему All()
ведет себя так? Какую проблему он решает? Это нарушает принцип наименьшего удивления?
Я отметил этот вопрос как .NET 3.5, хотя поведение также относится и к .NET 4.0.
РЕДАКТИРОВАТЬ Хорошо, поэтому я понимаю логический аспект этого, столь превосходно изложенный Джейсоном и остальными вами. По общему признанию, пустая коллекция является чем-то вроде краевого случая. Я предполагаю, что мой вопрос связан с борьбой, потому что что-то логично, это не значит, что это обязательно имеет смысл, если вы не в правильном настроении.