2014-06-27 12 views
6

Nell'attuare IEqualityComparer<Product> (Product è una classe), ReSharper lamenta che il controllo nullo sotto è sempre falso:In caso di implementazione di IEqualityComparer, il controllo GetHashCode deve essere annullato?

public int GetHashCode(Product product) 
{ 
    // Check whether the object is null. 
    if (Object.ReferenceEquals(product, null)) 
    return 0; 

    // ... other stuff ... 
} 

(Esempio di codice da MSDN VS.9 documentation of Enumerable.Except)

ReSharper può essere sbagliato, ma durante la ricerca di un risposta, mi sono imbattuto nel official documentation for IEqualityComparer<T> che ha un esempio in cui nulla non viene controllato per:

public int GetHashCode(Box bx) 
{ 
    int hCode = bx.Height^bx.Length^bx.Width; 
    return hCode.GetHashCode(); 
} 

Inoltre, la documentazione per GetHashCode() states viene generato quando ArgumentNullException viene generato quando "Il tipo di oggetto è un tipo di riferimento e l'oggetto è null".

Quindi, quando si implementa IEqualityComparer dovrebbe GetHashCode verificare null e, in tal caso, cosa deve fare con null (generare un'eccezione o restituire un valore)?

Sono interessato soprattutto alla documentazione ufficiale di .NET Framework che specifica in un modo o nell'altro se è necessario verificare null.

risposta

7

ReSharper è errato.

Ovviamente il codice che scrivi può chiamare quel particolare metodo GetHashCode e passare in un valore null. Tutti i metodi noti come potrebbero garantire che ciò non accadrà mai, ma ovviamente ReSharper può solo prendere in considerazione il codice (pattern) esistente.

Quindi, in questo caso, controllare null e fare la "cosa giusta".


Corollario: se il metodo in questione era privato, quindi ReSharper potrebbe analizzare (anche se non sono sicuro che lo fa) il codice pubblico e verificare che non v'è infatti alcun modo che questo particolare metodo privato sarà chiamato con un riferimento null, ma poiché è un metodo pubblico e uno disponibile tramite un'interfaccia, quindi

ReSharper è errato.

+0

Ovviamente, la "cosa giusta" è [up per dibattito] (http://stackoverflow.com/questions/10723458/should-the-hash-code-of-null-always-be-zero-in-net? rq = 1) quando si considera che la documentazione afferma che un 'ArgumentNullExpection' dovrebbe essere lanciato ma che le classi incorporate .NET non gettare effettivamente su null. – FriendlyGuy

2

La documentazione dice che i valori nulli non dovrebbero mai essere lavabili e che il tentativo di farlo dovrebbe sempre comportare un'eccezione.

Ovviamente, sei libero di fare quello che vuoi. Se vuoi creare una struttura basata sull'hash per cui le chiavi Null sono valide, sei libero di farlo, in questo caso devi semplicemente ignorare questo avviso.

+0

Corretto, comunque mi chiedo perché il resharper dice che il controllo nullo è sempre falso ... – digEmAll

+1

@digEmAll Perché crede nella documentazione. – Servy

Problemi correlati