2011-01-28 13 views
6

sto cercando il seguente:Impossibile confrontare T value1 con T value2 = default (T). Perché e come farlo in C#?

T value1 = el.value; // it's of type T already 
T value2 = default(T); 
if (value1 != value2) // gives the following error: Operator '!=' cannot be applied to operands of type 'T' and 'T' 
{ 
    // ... 
} 

Così, come potrei confrontare i due valori? E perché si verifica questo errore?

Grazie in anticipo!

+0

Assicurarsi T implementa le classi di tipo iCompare-ish, e il metodo o la classe che definisce T ha quei riferimenti nella dichiarazione. – asawyer

risposta

11

È possibile utilizzare un vincolo di where T : IEquatable<T> come detto Henk, o ignorare i vincoli e l'uso:

if (!EqualityComparer<T>.Default.Equals(value1, value2)) 
+0

Ho visto che il framework usa quel metodo per testare l'uguaglianza, sembra una buona strada da percorrere, anche se è un po 'prolisso. –

+0

Penso che questo sia il modo più semplice. Grazie! – Girardi

+0

@Ani: hai ragione. Avevo dimenticato che non esiste un'interfaccia IEquatable non generica. Modificherà. –

3

tuo circostante classe generica dovrebbe elencare un vincolo: T : IEquatable<T>

E poi si deve usare value1.Equals(value2)

La ragione di tutto questo è che non tutti i tipi definiscono operatore ==

+0

@ani: hai ragione, l'ho rimosso. Immagine della mia immaginazione. –

+0

Otterrai una 'NullReferenceException' se' value1' è 'null'. – nicodemus13

2

Cosa c'è di sbagliato in questo ?

if (!value1.Equals(value2)) 

dovrebbe essere "oggetto croce" .. :)

+2

Personalmente non mi piace l'asimmetria di quello. E ovviamente getta se 'value1 == null' – CodesInChaos

0

Un'altra cosa che si potrebbe fare è definire l'operatore di confronto (in realtà, l'operatore di differenza qui) per essere in grado di confrontare elementi del tipo T. Di per sé, il compilatore non può davvero sapere cosa intendi quando scrivi value1 != value2, tranne se l'operatore è stato definito in precedenza .

Per definire un operatore, utilizza

public operator!=(T a, T b) { 
    // Comparison code; returns true or false 
} 
+0

Penso che 'T' sia un parametro generico, quindi probabilmente non è possibile. – CodesInChaos

+0

Funziona solo quando il compilatore conosce (esattamente) cosa è T. –

1

se utilizzare value1.equals (value2) allora avete un problema con valori nulli. Meglio:
Object.equalsQ (valore1, valore2)

O per i tipi di riferimento (attenzione):
object.referenceEquals (valore1, valore2)

1

Non tutti i tipi hanno un'implementazione di default dell'operatore == . Per le classi, l'operazione predefinita == consiste nel confrontare i riferimenti. Per le strutture, non esiste un'implementazione predefinita di questo tipo.

È possibile aggiungere vincoli di tipo ai parametri di tipo generico in C#. Sfortunatamente, non è possibile definire un vincolo che impone al tipo di avere un'implementazione dell'operatore ==. Il meglio che puoi fare è forzare il tipo a essere una classe: where T: class. An article about type parameter constraints in C#

1

provare

Equals(value1, value2) 

Un buon modo per evitare di ref nullo

Problemi correlati