Jak mogę sprawdzić w Linq, czy kolekcja nie zawiera obiektu. IE Przeciwieństwo Any<T>
.
Mógłbym odwrócić wynik za pomocą a, !
ale ze względu na czytelność zastanawiałem się, czy istnieje lepszy sposób na zrobienie tego? Czy powinienem sam dodać rozszerzenie?
!
?Contains
,Exists
?None<T>
. Często używam takich niestandardowych rozszerzeń dla czytelności (na przykład nie lubię!dictionary.ContainsKey(key)
składni, więcdictionary.NoKey(key)
zamiast tego zaimplementowałem .ConcurrentDictionary
, ponieważ jest to bardzo przydatnaGetOrAdd
metoda, nawet jeśli nie potrzebuję współbieżności.Odpowiedzi:
Możesz łatwo utworzyć
None
metodę rozszerzenia: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); }
źródło
Przeciwieństwem sprawdzenia, czy jakikolwiek (przynajmniej jeden) rekord spełnia określone kryteria, byłoby sprawdzenie, czy wszystkie rekordy nie spełniają kryteriów.
Nie opublikowałeś pełnego przykładu, ale jeśli chciałeś czegoś takiego jak przeciwieństwo:
var isJohnFound = MyRecords.Any(x => x.FirstName == "John");
Możesz użyć:
var isJohnNotFound = MyRecords.All(x => x.FirstName != "John");
źródło
var isJohnNotFound = !MyRecords.All(x => x.FirstName == "John");
!MyRecords.All(x => InvalidNames.Any(n => n == x.Name));
Więc sprawdź każdy wpis na liście nieprawidłowych nazw, tylko jeśli żadna nie pasuje, wynik będzie prawdziwy.Oprócz dodanych odpowiedzi, jeśli nie chcesz zawijać
Any()
metody, możesz zaimplementowaćNone()
w następujący sposób:public static bool None<TSource>(this IEnumerable<TSource> source) { if (source == null) { throw new ArgumentNullException(nameof(source)); } using (IEnumerator<TSource> enumerator = source.GetEnumerator()) { return !enumerator.MoveNext(); } } public static bool None<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) { if (source == null) { throw new ArgumentNullException(nameof(source)); } if (predicate == null) { throw new ArgumentNullException(nameof(predicate)); } foreach (TSource item in source) { if (predicate(item)) { return false; } } return true; }
Oprócz tego w przypadku przeciążenia bez parametrów można zastosować
ICollection<T>
optymalizację, która w rzeczywistości nie istnieje w implementacji LINQ.ICollection<TSource> collection = source as ICollection<TSource>; if (collection != null) { return collection.Count == 0; }
źródło
Znalazłem ten wątek, gdy chciałem dowiedzieć się, czy kolekcja nie zawiera jednego obiektu, ale nie chcę sprawdzać, czy wszystkie obiekty w kolekcji spełniają podane kryteria. Skończyło się na tym, że zrobiłem taki czek:
var exists = modifiedCustomers.Any(x => x.Key == item.Key); if (!exists) { continue; }
źródło