Часто я хочу проверить, соответствует ли предоставленное значение одному в списке (например, при проверке):
if (!acceptedValues.Any(v => v == someValue))
{
// exception logic
}
Недавно я заметил, что ReSharper просит меня упростить эти запросы:
if (acceptedValues.All(v => v != someValue))
{
// exception logic
}
Очевидно, что это логически идентично, возможно, немного более читабельно (если вы много занимались математикой), мой вопрос: приводит ли это к снижению производительности?
Такое чувство, что оно должно (то есть .Any()
звучит так, как будто оно короткое замыкание, тогда как .All()
звучит так , как будто это не так), но мне нечем это обосновать. У кого-нибудь есть более глубокие знания относительно того, разрешат ли запросы то же самое, или ReSharper вводит меня в заблуждение?
if (!sequence.Any(v => v == true))
. Если вы хотите продолжить , только если все , что соответствует к определенной спецификации:if (sequence.All(v => v < 10))
.Ответы:
Реализация в
All
соответствии с ILSpy (как я на самом деле пошел и посмотрел, а не «ну, этот метод работает немного как ...» я мог бы сделать, если бы мы обсуждали теорию, а не влияние).Реализация
Any
согласно ILSpy:Конечно, может быть небольшая разница в произведенном IL. Но нет, нет, нет. IL в значительной степени такой же, но для очевидной инверсии возврата true при совпадении предикатов и возврата false при несовпадении предикатов.
Это, конечно, только linq-для-объектов. Возможно, что какой-то другой поставщик linq рассматривает одного из них гораздо лучше, чем другого, но тогда, если бы это было так, случайным образом, какой из них получил более оптимальную реализацию.
Казалось бы, правило сводится исключительно к тому, кто чувствует себя
if(determineSomethingTrue)
проще и понятнее, чемif(!determineSomethingFalse)
. И, честно говоря, я думаю, что у них есть некоторая точка в том, что меня частоif(!someTest)
смущает *, когда есть альтернативный критерий равной многословности и сложности, который вернул бы значение true для условия, в котором мы хотим действовать. Тем не менее, на самом деле, я лично не нахожу ничего, чтобы отдавать предпочтение одной из двух альтернатив, которые вы предоставляете, и, возможно, очень немного склонялся бы к первой, если бы предикат был более сложным.* Не сбивающий с толку, поскольку я не понимаю, но сбивающий с толку, поскольку я беспокоюсь, что есть некая тонкая причина для решения, которое я не понимаю, и требуется несколько умственных пропусков, чтобы понять, что «нет, они просто решили сделать так, подожди, что я снова посмотрел на этот кусочек кода? ... "
источник
Any
вернетсяfalse
и, следовательно!Any
, вернетсяtrue
, поэтому они идентичны.!test.Any(x => x.Key == 3 && x.Value == 1)
этого использованияAll
являетсяtest.All(x => !(x.Key == 3 && x.Value == 1))
(что действительно эквивалентноtest.All(x => x.Key != 3 || x.Value != 1)
).Возможно, эти методы расширения сделают ваш код более читабельным:
Теперь вместо твоего оригинала
ты мог бы сказать
источник
Оба будут иметь одинаковую производительность, потому что оба останавливают перечисление после того, как может быть определен результат -
Any()
по первому элементу переданный предикат оцениваетсяtrue
иAll()
по первому элементу, по которому оценивается предикатfalse
.источник
All
короткие замыкания при первом несовпадении, так что это не проблема.Одна область тонкости заключается в том, что
Правда. Все элементы в последовательности являются четными.
Подробнее об этом методе см. В документации по Enumerable.All .
источник
bool allEven = !Enumerable.Empty<int>().Any(i => i % 2 != 0)
это тоже правда.All()
определяет, все ли элементы последовательности удовлетворяют условию.Any()
определяет, удовлетворяет ли какой-либо элемент последовательности условию.источник
По этой ссылке
источник
Как и другие ответы хорошо освещены: речь идет не о производительности, а о ясности.
Существует широкая поддержка для обоих ваших вариантов:
Но я думаю, что это может обеспечить более широкую поддержку :
Простое вычисление логического значения (и присвоение ему имени) перед отрицанием чего-либо многое проясняет в моей памяти.
источник
Если вы посмотрите на источник Enumerable, вы увидите, что реализация
Any
иAll
довольно близка:Невозможно, чтобы один метод был значительно быстрее, чем другой, поскольку единственное различие заключается в логическом отрицании, поэтому предпочтение читаемости ложному выигрышу в производительности.
источник