70 votes

c# comparer deux valeurs génériques

Double Possible:
Ne pouvez pas l'opérateur == être appliquée à des types génériques en C#?

J'ai codé quelque chose comme ceci:

public bool IsDataChanged()
{           
    T value1 = GetValue2;
    T value2 = GetValue1();

    return (valueInDB != valueFromView);
}

Droit maintenant, la fonction n'est pas compilé avec le message d'erreur "Opérateur '!=' ne peut pas être appliquée à des opérandes de type " T " et "T"". Que dois-je faire pour que cela fonctionne ?

126voto

ShuggyCoUk Points 24204

Vous ne pouvez pas utiliser les opérateurs sur les types génériques (sauf pour les foo == null qui est spécial tubé), sauf si vous ajoutez T : classe pour indiquer qu'il s'agit d'un type de référence (alors foo == bar est légal)

Utiliser EqualityComparer<T>.Défaut de le faire pour vous. Cela permettra de ne pas travailler sur des types qui ne fournissent qu'un opérateur surcharge == sans aussi:

  • mettre en oeuvre IEquatable<T>
  • remplace objet.Equals()

En général, la mise en œuvre de l'opérateur == et pas aussi en train de faire au moins un de ces serait une très mauvaise idée de toute façon ce n'est donc pas susceptible d'être un problème.

public bool IsDataChanged<T>()
{           
    T value1 = GetValue2;
    T value2 = GetValue1();

    return !EqualityComparer<T>.Default.Equals(valueInDB, valueFromView);
}

Si vous ne limitez pas à l' IEquatable<T> puis le EqualityComparer de secours par défaut peut causer de boxe lorsqu'il est utilisé avec des types de valeur si elles ne mettent pas en oeuvre IEquatable<T> (si vous contrôlez les types sont utilisés, cela ne peut pas d'importance). Je suis en supposant que vous utilisiez =! pour des performances bien donc restreindre le type Générique permettra d'éviter accidentelle de boxe via l'Objet.Equals(object) de l'itinéraire.

5voto

CalvinR Points 313

Cela devrait fonctionner pour vous. public bool test(test T, T test2) où T : classe { retour (test != test2); }

C'est simplement collé à partir d'exemples qui ont fait des observations sur votre question.

3voto

devio Points 22981

Votre type de besoins pour mettre en œuvre les IComparable ou IEquatable interface.

Probablement, vous avez ensuite besoin de réécrire un!=b !(a==b), ou appelez le CompareTo() ou la méthode Equals() explicitement.

0voto

Jay S Points 3988

Vous pouvez surcharger le .Méthode Equals() sur l'objet et modifier votre évaluation:

return (!valueInDB.Equals(valueFromView));

En supposant que valueInDB et valueFromView sont des objets. Votre exemple les variables ne sont pas nommés les mêmes que ceux utilisés dans la comparaison, j'ai donc eu à assumer.

EDIT: j'Ai battu en 3 secondes! Une note sur la surcharge, si vous avez besoin de comparer des valeurs au sein d'un type de base .Equals() de la classe de l'Objet ne sera pas suffisant, car il ne fera qu'une mémoire de comparer les types complexes. Vous aurez besoin de la surcharge et de la mise en place de la façon dont vous souhaitez que l'objet à comparer.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X