Methoden bei vergleichbaren Typen überschreiben

     TypeName

OverrideMethodsOnComparableTypes

CheckId

CA1036

Kategorie

Microsoft.Design

Unterbrechende Änderung

NonBreaking

Ursache

Von einem öffentlichen oder geschützten Typ wird die System.IComparable-Schnittstelle implementiert. System.Object.Equals wird jedoch nicht überschrieben, bzw. der sprachspezifische Gleichheits-, Ungleichheits-, Kleiner-als- oder Größer-als-Operator wird nicht überladen. Die Regel meldet keinen Verstoß, wenn der Typ nur eine Implementierung der Schnittstelle erbt.

Regelbeschreibung

Typen, die eine benutzerdefinierte Sortierreihenfolge definieren, implementieren die IComparable-Schnittstelle. Die CompareTo-Methode gibt einen Ganzzahlwert zurück, der die richtige Sortierreihenfolge für zwei Instanzen des Typs angibt. Diese Regel identifiziert Typen, die eine Sortierreihenfolge festlegen. Dies impliziert, dass die gewöhnliche Bedeutung von Gleichheit, Ungleichheit, kleiner als und größer als nicht gilt. Wenn Sie eine Implementierung von IComparable angeben, muss in der Regel auch Equals überschrieben werden, damit Werte zuückgegeben werden, die mit CompareTo konsistent sind. Wenn Sie Equals überschreiben und den Programmcode in einer Sprache schreiben, die Operatorüberladungen unterstützt, müssen Sie auch Operatoren angeben, die mit Equals konsistent sind.

Behandlung von Verstößen

Um einen Verstoß gegen diese Regel zu korrigieren, überschreiben Sie Equals. Wenn die Programmiersprache das Überladen von Operatoren unterstützt, geben Sie die folgenden Operatoren an:

  • op_Equality

  • op_Inequality

  • op_LessThan

  • op_GreaterThan

In C# werden diese Operatoren mit den folgenden Token dargestellt: ==, !=, < und >

Warnungsausschluss

Eine Warnung dieser Regel kann gefahrlos ausgeschlossen werden, wenn der Verstoß durch fehlende Operatoren verursacht wird und die Programmiersprache das Überladen von Operatoren nicht unterstützt, wie dies bei Visual Basic .NET der Fall ist.

Beispiel

Das folgende Beispiel enthält einen Typ, von dem IComparable ordnungsgemäß implementiert wird. Codekommentare identifizieren die Methoden, die verschiedenen Regeln entsprechen, die sich auf Equals und auf die IComparable-Schnittstelle beziehen.

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);
      }  
   }
}

Die folgende Anwendung testet das Verhalten der weiter oben dargestellten IComparable-Implementierung.

using System;
using 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);      
   }
}

Siehe auch

Referenz

Richtlinien für die Implementierung der Equals-Methode und des Gleichheitsoperators (==)
System.IComparable
System.Object.Equals