2010-12-08 59 views
4

Ce code produit True.ReSharper 5.x, HashSet Contient() et "Affectation null possible"

using System; 
using System.Collections.Generic; 

public class Default 
{ 
    public static void Main(string[] args) 
    { 
     HashSet<string> foo = new HashSet<string>(); 
     foo.Add(null); 
     Console.WriteLine(foo.Contains(null)); 
    } 
} 

Le null dans mon contains() appel a un gribouillis bleu en dessous, avec l'avertissement suivant:

possible cession 'null' à l'entité marquée avec l'attribut 'NotNull'

Lorsque je suspend ReSharper, l'avertissement disparaît.

Pourquoi cet avertissement se produit-il? Étant donné que je peux ajouter null à un HashSet, ce qui est cassé à propos de mon vouloir vérifier null dans un HashSet?

EDIT: .NET 3.5, VS2010

+0

ReSharper semble être cassé. Tout le reste semble bien: Votre code s'exécute sans exception, Reflector ne montre aucune vérification null ou aucun attribut NonNull pour HashSet .Add ou HashSet .Contains. – dtb

+0

devriez-vous vraiment ajouter Null à un HashSet? –

+0

Dans mon code réel, le Contient (null) est dans une spécification qui vérifie que null, en fait, n'a * pas * été ajouté à un HashSet à un moment où le développeur pourrait être tenté de le faire. – lance

Répondre

3

Je dirais que ce bogue dans ReSharper. Le type HashSet<T> est conçu pour gérer les valeurs null. Ceci est évident en examinant le code dans le réflecteur. En particulier, la méthode InternalGetHashCode qui a un contrôle explicite pour null et fournit un code de hachage par défaut de 0.

Le seul cas où cela pourrait se présenter un problème pour les cas personnalisés IEqualityComparer<T> transmis à la HashSet<T> qui ne tiennent pas compte null. Je dirais que c'est assez rare bien que les contrôles null font partie du modèle d'égalité standard pour les types de référence dans .Net.

Note: Pour être clair, je n'encourage certainement pas les gens à ajouter null à leur collection. En fait, j'encouragerais le contraire. Juste en soulignant que pour une raison quelconque, HashSet<T> semble autoriser explicitement ce scénario.

+0

Juste parce que vous pouvez ajouter Null, ne veut pas nécessairement dire que c'est une bonne idée;) –

+0

@Mitch, je n'ai pas dit que c'était une bonne idée juste que 'HashSet ' pense clairement mauvais code devrait être autorisé;) – JaredPar

+0

lol! Bon point :) +1 –

0

Je suppose que ce pourrait être parce que la méthode HashSet<T>.Contains est une implémentation de ICollection<T>.Contains.

D'autres implémentations de ICollection<T> peuvent ne pas autoriser les valeurs NULL.

Que ce soit le cas ou non, il n'y a aucune raison pour que l'ensemble de règles ReSharper ne puisse pas être affiné pour ne pas signaler cela comme une erreur potentielle.