Come confrontare due elementi dello stesso tipo generico ma non vincolato per l'uguaglianza? [duplicare]
Domanda
Possibile duplicato:
Può & # 8217; t operator == essere applicato a tipi generici in C #?
Ho la seguente classe generica e il compilatore si lamenta che " Operator '!=' cannot be applied to operands of type 'TValue' and 'TValue'
" (vedi CS0019 ):
public class Example<TValue>
{
private TValue _value;
public TValue Value
{
get { return _value; }
set
{
if (_value != value) // <<-- ERROR
{
_value= value;
OnPropertyChanged("Value");
}
}
}
}
Se vincolo TValue
a class
, potrei usare Object.Equals()
. Dato che ne ho bisogno per entrambe le strutture e le classi, sarei molto felice se potessi evitarlo.
Quindi la domanda è: come posso confrontare due elementi dello stesso tipo generico non vincolato per l'uguaglianza?
Soluzione
Hai provato qualcosa del genere?
public class Example<TValue>
{
private TValue _value;
public TValue Value
{
get { return _value; }
set
{
if (!object.Equals(_value, value))
{
_value = value;
OnPropertyChanged("Value");
}
}
}
}
Altri suggerimenti
Tre opzioni:
- Vincola TValue per implementare
IEquatable<TValue>
e quindi chiamax.Equals(y)
- Prendi un altro parametro di tipo
IEqualityComparer<TValue>
e usalo - Utilizzare
EqualityComparer<TValue>.Default
per eseguire i confronti
Puoi sempre mescolare e abbinare le opzioni 2 e 3, ovviamente - default al comparatore predefinito, ma consenti anche di fornirne uno specifico.
- Equals () per i tipi di valore
- ReferenceEquals () per i tipi di riferimento
IComparable è un'opzione?
public class Example<TValue> where TValue: IComparable
{
private TValue _value;
public TValue Value
{
get { return _value; }
set
{
if (_value.CompareTo(value) != 0)
{
_value = value;
OnPropertyChanged("Value");
}
}
}
}
Penso che l'operatore !=
non possa essere applicato qui perché ci sono casi in cui non può essere utilizzato. Ad esempio, ==
non può essere utilizzato per confrontare le strutture, a meno che gli operatori di confronto (int != int
<=>) non siano sovraccarichi.
Ovviamente, puoi confrontare le strutture linguistiche, come <=>, ma non sono sicuro di come sia implementato.
Quindi, poiché TValue può essere una struttura personalizzata , non può utilizzare l'operatore <=>.
public static bool operator ==(EntityBase<T> entity1, EntityBase<T> entity2)
{
if ((object)entity1 == null && (object)entity2 == null)
{
return true;
}
if ((object)entity1 == null || (object)entity2 == null)
{
return false;
}
if (Comparer<T>.Default.Compare(entity1.Id, entity2.Id) != 0)
{
return false;
}
return true;
}