2009-12-13 1 views
34

Quanto segue non può essere compilato:di prova per l'uguaglianza al valore predefinito

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

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

Non posso usare value == null perché T può essere una struct.
Non riesco a utilizzare value.Equals(default(T)) perché value può essere null.
Qual è il modo corretto di verificare l'uguaglianza con il valore predefinito?

+2

risposto per commentare; e per informazioni, 'EqualityComparer ' è l'implementazione standard utilizzata dal BCL, ad esempio in 'Dictionary <,>'. –

+2

possibile duplicato di http://stackoverflow.com/questions/65351/null-or-default-comparsion-of-generic-argument-in-c-sharp – nawfal

risposta

53

Per evitare di boxe per struct/Nullable<T>, vorrei utilizzare:

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

Questo supporta qualsiasi T che implementano IEquatable<T>, utilizzando object.Equals come backup, e gestisce null ecc. (e gli operatori sollevati per Nullable<T>) automaticamente.

C'è anche Comparer<T>.Default che gestisce i test di confronto. Questo gestisce T che implementa IComparable<T>, rientra in IComparable - di nuovo gestendo null e gli operatori sollevati.

+0

Stai dicendo che 'EqualityComparer .Default.Equals' ha prestazioni migliori di' Object.Equals', o che darebbe un valore corretto in alcuni casi che 'Object.Equals' non lo sarebbe? – Greg

+9

Prestazioni migliori (meno boxe); considera 'T = int'; per chiamare 'object.Equals' deve box' value' e 'default (T)' - sono due allocazioni heap extra + GC. Usando 'EqualityComparer ' ha 3 diverse implementazioni sottostanti - 'class',' Nullable 'e' struct' - può quindi fare tutto (compresi i test 'nulli') senza ** qualsiasi ** boxing. Il lavoro di capire quale implementazione utilizzare viene eseguita una sola volta per tipo e memorizzata nella cache, quindi è ancora molto veloce. –

+0

Grazie, Marc! La tua spiegazione è meravigliosa – Greg

21

Che dire

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

Sapevo che sarebbe stato semplice. Grazie. – Greg

+1

+1. Provato. Funziona correttamente con vari tipi: 'MyMethod (0); MyMethod (null); MyMethod (null); '- in ogni caso restituisce true. –