Dictionary.FirstOrDefault () comment déterminer si un résultat a été trouvé

J’ai (ou voulais avoir) du code comme celui-ci:

IDictionary dict = new Dictionary(); // ... Add some stuff to the dictionary. // Try to find an entry by value (if multiple, don't care which one). var entry = dict.FirstOrDefault(e => e.Value == 1); if ( entry != null ) { // ^^^ above gives a comstack error: // Operator '!=' cannot be applied to operands of type 'System.Collections.Generic.KeyValuePair' and '' } 

J’ai aussi essayé de changer la ligne incriminée comme ceci:

 if ( entry != default(KeyValuePair) ) 

Mais cela donne aussi une erreur de compilation:

 Operator '!=' cannot be applied to operands of type 'System.Collections.Generic.KeyValuePair' and 'System.Collections.Generic.KeyValuePair' 

Qu’est-ce qui donne ici?

La réponse de Jon fonctionnera avec Dictionary , car il ne peut pas y avoir de valeur de clé nulle dans le dictionnaire. Cela ne fonctionnerait pas avec Dictionary , cependant, comme cela ne représente pas une valeur de clé nulle … le mode “fail” se retrouverait avec une clé de 0.

Deux options:

Ecrivez une méthode TryFirstOrDefault , comme ceci:

 public static bool TryFirstOrDefault(this IEnumerable source, out T value) { value = default(T); using (var iterator = source.GetEnumerator()) { if (iterator.MoveNext()) { value = iterator.Current; return true; } return false; } } 

Alternativement, projetez vers un type nullable:

 var entry = dict.Where(e => e.Value == 1) .Select(e => (KeyValuePair?) e) .FirstOrDefault(); if (entry != null) { // Use entry.Value, which is the KeyValuePair } 

Faites-le de cette façon:

 if ( entry.Key != null ) 

Le fait est que la méthode FirstOrDefault renvoie un KeyValuePair qui est un type de valeur , donc il ne peut jamais être null . Vous devez déterminer si une valeur a été trouvée en vérifiant si au moins une de ses propriétés Key , Value a sa valeur par défaut. Key est de type ssortingng , donc vérifier que null un sens, étant donné que le dictionnaire ne peut pas avoir un élément avec une clé null .

Autres approches possibles:

 var entry = dict.Where(e => e.Value == 1) .Select(p => (int?)p.Value) .FirstOrDefault(); 

Cela projette les résultats dans une collection d’ints nullables, et si celle-ci est vide (pas de résultats), vous obtenez un null – vous ne pouvez pas vous tromper sur les int pour une recherche réussie.

Quels que soient les types de clé et de valeur, vous pouvez faire quelque chose comme ceci:

  static void Main(ssortingng[] args) { var dict = new Dictionary { {3, "ABC"}, {7, "HHDHHGKD"} }; bool found = false; var entry = dict.FirstOrDefault(d => d.Key == 3 && (found=true)); if (found) { Console.WriteLine("found: " + entry.Value); } else { Console.WriteLine("not found"); } Console.ReadLine(); } 
 public static TValue FirstOrDefault(this Dictionary dictionary, Func, bool> where) { foreach (var kv in dictionary) { if (where(kv)) return kv.Value; } return default; } 

pour les types de valeur nullable, vérifiez simplement.

 if ( entry.Value != null ) { //do stuff } 

pour les types non nullables, vérifiez à nouveau la valeur par défaut, pour int, 0.

 if ( entry.Value != 0) { //do stuff } 

Ce n’est probablement pas la meilleure approche, mais dans mes tests unitaires, cela semble être rapide et sale:

 try { var input = _dictionaryOfInputs.First(item => item.Key == interval); return input.Value.InvoiceAmount; } catch { return 0; } 

Pour être honnête, lancer l’object ou utiliser une instruction select est inutile, je ne me fierais pas non plus à un try try.

Puisque vous utilisez de toute façon Linq, quel est le problème avec l’utilisation de .Any?

 var entry; if (dict.Any(e => e.Value == 1)) { // Entry was found, continue work... entry = dict.FirstOrDefault(e => e.Value == 1); } else { // Entry was not found. entry = -1; } 

Evidemment, jouez avec cela pour adapter votre solution, mais c’est une vérification assez rapide qui s’arrête si elle trouve un élément dans la collection avec cette valeur. Il ne vérifie donc pas toutes les valeurs si une correspondance a été trouvée.

Documentation MSDN: https://msdn.microsoft.com/en-us/library/bb534972(v=vs.110).aspx