Указатель NULL
- это тот, который указывает на никуда. Когда вы разыскиваете указатель p
, вы говорите «дайте мне данные в месте, хранящемся в« p ». Когда p
является нулевым указателем, местоположение, хранящееся в p
, является nowhere
, вы говорите «Дайте мне данные в месте« нигде ». Очевидно, он не может этого сделать, поэтому он выбрасывает NULL pointer exception
.
В общем, это потому, что что-то не было правильно инициализировано.
Реализация All
в соответствии с ILSpy (как в действительности я пошла и посмотрела, а не «хорошо, этот метод немного похож ...» Я мог бы сделать, если бы мы обсуждали теорию, а не влияние) .
public static bool All<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
{
if (source == null)
{
throw Error.ArgumentNull("source");
}
if (predicate == null)
{
throw Error.ArgumentNull("predicate");
}
foreach (TSource current in source)
{
if (!predicate(current))
{
return false;
}
}
return true;
}
Реализация Any
в соответствии с ILSpy:
public static bool Any<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
{
if (source == null)
{
throw Error.ArgumentNull("source");
}
if (predicate == null)
{
throw Error.ArgumentNull("predicate");
}
foreach (TSource current in source)
{
if (predicate(current))
{
return true;
}
}
return false;
}
Конечно, может быть какая-то тонкая разница в произведенном IL. Но нет, нет, нет. IL - это почти то же самое, но для очевидной инверсии возврата истины в соответствие с предикатом по сравнению с возвратом false при несоответствии предикатов.
Это, конечно, linq-for-objects. Возможно, что какой-то другой провайдер linq рассматривает один гораздо лучше, чем другой, но если это так, то довольно случайный, который получает более оптимальную реализацию.
Казалось бы, исключительно для тех, кто чувствует, что if(determineSomethingTrue)
проще и читабельнее, чем if(!determineSomethingFalse)
. И, честно говоря, я думаю, что у них немного точка в том, что я часто нахожу if(!someTest)
запутанной *, когда есть альтернативный тест с равной многословностью и сложностью, который вернет true для условия, на которое мы хотим действовать. Тем не менее, на самом деле, я лично не нахожу ничего, чтобы одобрить одну из двух альтернатив, которые вы даете, и, возможно, немного наклонился бы к первому, если бы предикат был более сложным.
* Не путайте, как в I don я не понимаю, но смущаю, как в том, что я беспокоюсь, что есть какая-то тонкая причина для решения, которое я не понимаю, и требуется несколько умственных пропусков, чтобы понять, что «нет, они просто решили сделать это таким образом, подождать, что было Я снова смотрю этот бит кода? ... "
Вы можете обнаружить, что эти методы расширения делают ваш код более удобочитаемым:
public static bool None<TSource>(this IEnumerable<TSource> source)
{
return !source.Any();
}
public static bool None<TSource>(this IEnumerable<TSource> source,
Func<TSource, bool> predicate)
{
return !source.Any(predicate);
}
Теперь вместо исходного
if (!acceptedValues.Any(v => v == someValue))
{
// exception logic
}
вы можете сказать
if (acceptedValues.None(v => v == someValue))
{
// exception logic
}
All
коротких замыканий в первом несоответствии, поэтому это не проблема.
Одна из областей тонкости заключается в том, что
bool allEven = Enumerable.Empty<int>().All(i => i % 2 == 0);
Является истинным. Все элементы в последовательности четные.
Подробнее об этом методе см. в документации для Enumerable.All .
Оба будут иметь одинаковую производительность, потому что обе стоп-перечисления после результата могут быть определены - Any()
по первому элементу, который переданный предикат оценивает true
и All()
в первом элементе, который предикат оценивает как false
.
All()
определяет, удовлетворяют ли все элементы последовательности условию. Any()
определяет, удовлетворяет ли любой элемент последовательности
var numbers = new[]{1,2,3};
numbers.All(n => n % 2 == 0); // returns false
numbers.Any(n => n % 2 == 0); // returns true
Поскольку другие ответы хорошо освещены: речь идет не о производительности, а о ясности.
Широкая поддержка обеих ваших опций:
if (!acceptedValues.Any(v => v == someValue))
{
// exception logic
}
if (acceptedValues.All(v => v != someValue))
{
// exception logic
}
Но я думаю, что это может обеспечить более широкую поддержку :
var isValueAccepted = acceptedValues.Any(v => v == someValue);
if (!isValueAccepted)
{
// exception logic
}
Просто вычисляя логическое (и именовав его), прежде чем отрицать что-либо, все это проясняет мне много.
Согласно этой ссылке
Any - проверяет хотя бы одно совпадение
All - проверяет, что все совпадают
< / BLOCKQUOTE>
Если вы посмотрите на Enumerable source , вы увидите, что реализация Any
и All
довольно близка:
public static bool Any<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) {
if (source == null) throw Error.ArgumentNull("source");
if (predicate == null) throw Error.ArgumentNull("predicate");
foreach (TSource element in source) {
if (predicate(element)) return true;
}
return false;
}
public static bool All<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) {
if (source == null) throw Error.ArgumentNull("source");
if (predicate == null) throw Error.ArgumentNull("predicate");
foreach (TSource element in source) {
if (!predicate(element)) return false;
}
return true;
}
ни один способ, чтобы один метод был значительно быстрее, чем другой, поскольку единственное различие заключается в булевом отрицании, поэтому предпочитают читаемость по сравнению с ложным выигрышем.
Any
вернетfalse
и, следовательно,!Any
вернетtrue
, поэтому они будут идентичны. – Jon Hanna 30 May 2013 в 11:31!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)
). – Jon Hanna 18 September 2013 в 15:05