2016-04-06 15 views
9

Di seguito viene fornito il codice, voglio solo confrontare due oggetti all'interno di una classe generica.Confronto di oggetti dattilografati nella classe generica

public bool Compare<T>() 
    { 
     T var1 = default(T); 
     T var2 = default(T);   
     return var1 == var2; 
     //Error CS0019 Operator '==' cannot be applied to operands of type 'T' and 'T' 
    } 

Qualcuno può spiegare perché non è possibile confrontare questi due oggetti in questa classe generica?

+0

È il 'predefinito (T)' proprio come un esempio, o è proprio questo il caso che vuoi confrontare? Altrimenti, direi che è sempre sempre 'true', a patto che l'implementatore di una struct non sia diventato completamente bizzarro con overriding' == '. – MicroVirus

risposta

-1

Non è possibile utilizzare l'== -operator sul Tipo T perché non è garantito che questo operatore sia definito su tale tipo. Imagine T è di tipo KeyValuePair ad esempio. Non si può scrivere il seguente:

var areEqual = (new KeyValuePair<string, string>("1", "1") == new KeyValuePair<string, string>("2", "2")) 

fare qualche vincolo sul tipo generico come where T : new() per consentire solo le classi in cui il default-valore è null.

EDIT: Come un vincolo solo le classi è abbastanza priva di senso, perché di riferimento tipi allways Default per null è possibile Unbox l'istanza di T-object e quindi chiamare la == -operator:

public bool Compare<T>() 
{ 
    object var1 = default(T); 
    object var2 = default(T); 
    if (var1 == null) return var1 == var2; 
    return var1.Equals(var2); 
} 

Ciò consente chiamare il metodo per entrambi i tipi di valore e di riferimento.

+0

Cosa succede se var1 è nullo? Non funzionerà –

+0

@MartinSwanepoel Buon punto, aggiornato. – HimBromBeere

+0

Ancora non funzionerà 'return var1 == var2;' –

1

Il tipo T non è necessariamente un tipo di riferimento, T è un argomento di tipo e può essere una classe o una struttura, quindi il compilatore non sarà in grado di effettuare tale ipotesi.

potete fare come

public bool Compare<T>() 
{   
     T var1 = default(T); 
     T var2 = default(T); 

     return !EqualityComparer<T>.Default.Equals(var1, var2); 
} 

Si può anche provare a fare T IComparable<T> oppure si può provare a utilizzare un IComparer<T> alla classe.

+0

Questo userà 'Object.Equals' (e' Object.GetHashCode') per 'T', a meno che' T: IEquatable ', nel qual caso lo usa. – MicroVirus

-1

È necessario limitare T all'interfaccia IEquatable<T>, quindi sarà possibile confrontarli chiamando il metodo Equals.

public bool Compare<T>(T var1, T var2) where T : IEquatable<T> 
{ 
    return var1.Equals(var2); 
} 
0

opzione rapida:

public bool Compare<T>() 
{ 
    var t1 = default(T); 
    var t2 = default(T); 
    return object.Equals(t1, t2); 
} 

Genericamente corretta opzione:

public bool Compare<T>() 
{ 
    var t1 = default(T); 
    var t2 = default(T); 
    return EqualityComparer<T>.Default.Equals(t1, t2); 
} 

stare attenti il ​​codice qui sotto, perché se t1 variabile è nulla si riceve un'eccezione

public bool Compare<T>() 
{ 
    var t1 = default(T); 
    var t2 = default(T); 
    return t1.Equals(t2); 
}