Partager via


Substituer les méthodes sur les types Comparable

Mise à jour : novembre 2007

TypeName

OverrideMethodsOnComparableTypes

CheckId

CA1036

Catégorie

Microsoft.CSharp

Modification avec rupture

Modification sans rupture

Cause

Un type public ou protégé implémente l'interface System.IComparable et ne substitue pas Object.Equals, ni ne surcharge l'opérateur égal à, différent de, inférieur à ou supérieur à propre au langage. La règle ne rapporte pas d'infraction si le type hérite seulement d'une implémentation de l'interface.

Description de la règle

Les types qui définissent un ordre de tri personnalisé implémentent l'interface IComparable. La méthode CompareTo retourne une valeur entière qui indique l'ordre de tri approprié pour deux instances du type. Cette règle identifie des types qui définissent un ordre de tri, en impliquant que la signification ordinaire des opérations égal à, différent de, supérieur à et inférieur à ne s'applique pas. Lorsque vous fournissez une implémentation de IComparable, il est généralement nécessaire de substituer aussi Equals afin qu'il retourne des valeurs cohérentes avec CompareTo. Si vous substituez Equals et codez dans un langage qui prend en charge les surcharges d'opérateur, vous devez également fournir des opérateurs cohérents avec Equals.

Comment corriger les violations

Pour corriger une violation de cette règle, substituez Equals. Si votre langage de programmation prend en charge la surcharge d'opérateur, fournissez les opérateurs suivants :

  • op_Equality

  • op_Inequality

  • op_LessThan

  • op_GreaterThan

En C#, les jetons utilisés pour représenter ces opérateurs sont : ==! =, <, et >.

Quand supprimer les avertissements

Il est possible de supprimer sans risque un avertissement de cette règle lorsque la violation est provoquée par des opérateurs manquants et lorsque votre langage de programmation ne prend pas en charge la surcharge d'opérateur, comme c'est le cas avec Visual Basic .NET.

Exemple

L'exemple suivant contient un type qui implémente correctement IComparable. Les commentaires de code identifient les méthodes qui satisfont différentes règles en rapport avec Equals et l'interface IComparable.

using System;
using System.Globalization;

namespace DesignLibrary
{
   // Valid ratings are between A and C.
   // A is the highest rating; it is greater than any other valid rating.
   // C is the lowest rating; it is less than any other valid rating.

   public class RatingInformation :IComparable 
   {
      private string rating;

      public RatingInformation (string s)
      {
         string v = s.ToUpper(CultureInfo.InvariantCulture);
         if (v.CompareTo("C") > 0 || v.CompareTo("A") < 0 || v.Length != 1)
         {
            throw new ArgumentException("Invalid rating value was specified.");
         }
         rating = v;
      }

      public int CompareTo ( object obj)
      {
         if (!(obj is RatingInformation))
         {
            throw new ArgumentException(
               "A RatingInformation object is required for comparison.");
         }
         // Ratings compare opposite to normal string order,
         // so reverse the value returned by String.CompareTo.
         return -1 * this.rating.CompareTo(((RatingInformation)obj).rating);
      }

      public string Rating 
      {
         get { return rating;}
      }

      // Omitting Equals violates rule: OverrideMethodsOnComparableTypes.
      public override bool Equals (Object obj)
      {
         if (!(obj is RatingInformation))
            return false;
         return (this.CompareTo(obj)== 0);
      }  

      // Omitting getHashCode violates rule: OverrideGetHashCodeOnOverridingEquals.
      public override int GetHashCode ()
      {
         char [] c = this.Rating.ToCharArray();
         return (int) c[0];
      }  
      // Omitting any of the following operator overloads 
      // violates rule: OverrideMethodsOnComparableTypes.
      public static bool operator == (RatingInformation r1, RatingInformation r2)
      {
         return r1.Equals(r2);
      }  
      public static bool operator != (RatingInformation r1, RatingInformation r2)
      {
        return !(r1==r2);
      }  
      public static bool operator < (RatingInformation r1, RatingInformation r2)
      {
         return (r1.CompareTo(r2) < 0);
      }  
      public static bool operator > (RatingInformation r1, RatingInformation r2)
      {
         return (r1.CompareTo(r2) > 0);
      }  
   }
}

L'application suivante teste le comportement de l'implémentation IComparable présentée précédemment.

using System;

namespace DesignLibrary
{
    public class Test
    {
       public static void Main(string [] args)
       {
          if (args.Length < 2)
          {
             Console.WriteLine ("usage - TestRatings  string 1 string2");
             return;
          }
          RatingInformation r1 = new RatingInformation(args[0]) ;
          RatingInformation r2 = new RatingInformation( args[1]);
          string answer;

          if (r1.CompareTo(r2) > 0)
             answer = "greater than";
          else if (r1.CompareTo(r2) < 0)
             answer = "less than";
          else
             answer = "equal to";

          Console.WriteLine("{0} is {1} {2}", r1.Rating, answer, r2.Rating);      
       }
    }
}

Voir aussi

Référence

Indications concernant l'implémentation de Equals et de l'opérateur d'égalité (==)

System.IComparable

Object.Equals