2009-12-13 4 views
34

qui suit ne compile pas:Test d'égalité à la valeur par défaut

public void MyMethod<T>(T value) 
{ 
    if (value == default(T)) 
    { 
     // do stuff 
    } 
} 

Erreur: Operator '==' cannot be applied to operands of type 'T' and 'T'

Je ne peux pas utiliser value == null parce T peut être un struct.
Je ne peux pas utiliser value.Equals(default(T)) car value peut être null.
Quelle est la bonne façon de tester l'égalité à la valeur par défaut?

+2

a répondu au commentaire; et pour info, 'EqualityComparer ' est l'implémentation standard utilisée par la BCL, par exemple dans 'Dictionary <,>'. –

+2

duplicata possible de http://stackoverflow.com/questions/65351/null-or-default-comparsion-of-generic-argument-in-c-sharp – nawfal

Répondre

53

Pour éviter la boxe pour struct/Nullable<T>, j'utiliser:

if (EqualityComparer<T>.Default.Equals(value,default(T))) 
{ 
    // do stuff 
} 

Cela soutient toute T qui mettent en œuvre IEquatable<T>, en utilisant object.Equals comme une sauvegarde, et gère null etc (et les opérateurs levés pour Nullable<T>) automatiquement. Il existe également Comparer<T>.Default qui gère les tests de comparaison. Cela gère T qui implémentent IComparable<T>, retombant à IComparable - en traitant à nouveau null et opérateurs levés.

+0

Êtes-vous en train de dire que 'EqualityComparer .Default.Equals' a de meilleures performances que' Object.Equals', ou qu'il donnerait une valeur correcte dans certains cas que 'Object.Equals' ne le ferait pas? – Greg

+9

Meilleure performance (moins de boxe); considérez 'T = int'; pour appeler 'object.Equals' il doit encadrer' value' et 'default (T)' - c'est deux allocations de tas supplémentaires + GC. En utilisant 'EqualityComparer ' il a 3 implémentations sous-jacentes différentes - 'class',' Nullable 'et' struct' - il peut alors tout faire (y compris les tests null) sans ** aucune ** boxe. Le travail de détermination de l'implémentation à utiliser est effectué une seule fois par type et mis en cache, donc toujours très rapide. –

+0

Merci, Marc! Ton explication est merveilleuse – Greg

21

Qu'en est-

object.Equals(value, default(T)) 
+0

Je savais que cela devrait être simple. Je vous remercie. – Greg

+1

+1. Testé. Fonctionne correctement avec différents types: 'MyMethod (0); MyMethod (null); MyMethod (null); 'dans chaque cas renvoie true. –

Questions connexes