web-dev-qa-db-fra.com

c # comparer deux valeurs génériques

Duplicata possible:
L'opérateur == ne peut-il pas être appliqué aux types génériques en C #?

J'ai codé quelque chose comme ça:

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

    return (valueInDB != valueFromView);
}

Pour l'instant, la fonction ne se compile pas avec l'erreur " L'opérateur '! =' Ne peut pas être appliqué aux opérandes de type 'T' et 'T'". Que dois-je faire pour que cette fonction fonctionne?

67
bernhardrusch

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

Utilisation EqualityComparer<T>. Par défaut, faites-le pour vous. Cela pas fonctionnera sur les types qui fournissent uniquement une surcharge d'opérateur pour == sans également:

  • mettre en place IEquatable<T>
  • remplace object.Equals ()

En général, l'implémentation de l'opérateur == et le fait de ne pas en faire au moins une serait de toute façon une très mauvaise idée, donc ce n'est probablement pas un problème.

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

    return !EqualityComparer<T>.Default.Equals(value1 , value2);
}

Si vous ne vous limitez pas à IEquatable<T> alors le repli par défaut d'EqualityComparer peut provoquer la boxe lorsqu'il est utilisé avec des types de valeur s'ils n'implémentent pas IEquatable<T> (si vous contrôlez les types utilisés, cela n'a pas d'importance). Je suppose que vous utilisiez =! pour les performances, si restreindre au type générique évitera la boxe accidentelle via la route Object.Equals (objet).

120
ShuggyCoUk

Cela devrait fonctionner pour vous.

public bool test<T>(T test, T test2) where T : class
{
    return (test != test2);
}

Ceci est simplement collé à partir des exemples qui ont été commentés sur votre question.

4
CalvinR

Votre type doit implémenter l'interface IComparable ou IEquatable .

Vous devrez probablement réécrire a! = B en tant que! (A == b), ou appeler explicitement la méthode CompareTo () ou Equals ().

3
devio

Vous pouvez surcharger la méthode .Equals () sur vos objets et modifier votre évaluation en:

return (!valueInDB.Equals(valueFromView));

En supposant que valueInDB et valueFromView sont des objets. Vos variables d'exemple ne sont pas nommées de la même manière que celles utilisées dans la comparaison, j'ai donc dû supposer.

EDIT: J'ai battu de 3 secondes! Remarque sur la surcharge, si vous avez besoin de comparer des valeurs au sein d'un type, le .Equals () de base de la classe Object ne sera pas suffisant, car il ne fera qu'une comparaison de mémoire pour les types complexes. Vous devrez surcharger et fournir l'implémentation de la façon dont vous souhaitez que l'objet soit comparé.

0
Jay S