Comment comparer deux éléments du même type générique mais non contraint pour l'égalité? [dupliquer]
Question
Double possible:
Peut & # 8217; opérateur t = = être appliqué à types génériques en C #?
J'ai la classe générique suivante et le compilateur se plaint que " Operator '!=' cannot be applied to operands of type 'TValue' and 'TValue'
" (voir CS0019 ):
public class Example<TValue>
{
private TValue _value;
public TValue Value
{
get { return _value; }
set
{
if (_value != value) // <<-- ERROR
{
_value= value;
OnPropertyChanged("Value");
}
}
}
}
Si je contrains TValue
à class
, je pourrais utiliser Object.Equals()
. Etant donné que j'en ai besoin pour les deux structures et les classes, je serais très heureux si je pouvais l'éviter.
La question est donc: comment puis-je comparer deux éléments du même type générique mais non contraint pour l'égalité?
La solution
Avez-vous essayé quelque chose comme ça?
public class Example<TValue>
{
private TValue _value;
public TValue Value
{
get { return _value; }
set
{
if (!object.Equals(_value, value))
{
_value = value;
OnPropertyChanged("Value");
}
}
}
}
Autres conseils
Trois options:
- contraignez TValue à implémenter
IEquatable<TValue>
puis appelezx.Equals(y)
- Prenez un autre paramètre de type
IEqualityComparer<TValue>
et utilisez-le - Utilisez
EqualityComparer<TValue>.Default
pour effectuer les comparaisons
Vous pouvez toujours mélanger et assortir les options 2 et 3, bien sûr - par défaut, le comparateur, mais également en autoriser un spécifique.
- est égal à () pour les types de valeur
- ReferenceEquals () pour les types de référence
IComparable est-il une option?
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");
}
}
}
}
Je pense que l'opérateur !=
ne peut pas être appliqué ici car il est parfois impossible de l'utiliser. Par exemple, ==
ne peut pas être utilisé pour comparer des structures, sauf si les opérateurs de comparaison (int != int
<=>) sont surchargés.
Bien sûr, vous pouvez comparer les structures de langage, comme <=>, mais je ne suis pas sûr de savoir comment cela est mis en œuvre.
Ainsi, TValue pouvant être une structure personnalisée , elle ne peut pas utiliser l'opérateur <=>.
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;
}