Sdílet prostřednictvím


CA1036: Přepište metody srovnatelných typů

Název_typu

OverrideMethodsOnComparableTypes

CheckId

CA1036

Kategorie

Microsoft.design

Změnit rozdělení

Bez rozdělení

Příčina

Chráněný nebo veřejný typ implementuje IComparable rozhraní a nemá přednost před Object.Equals a nejsou přetížení operátor jazyka pro rovnost, nerovnosti, menší nebo větší než.Pravidlo nehlásí porušení, pokud typ dědí pouze implementaci rozhraní.

Popis pravidla

Typy definující vlastní pořadí řazení implementovat IComparable rozhraní.CompareTo Metoda vrátí celočíselnou hodnotu označující správné pořadí řazení pro dvě instance typu.Toto pravidlo označuje typy nastavit pořadí řazení; To znamená, že běžná smyslu rovnosti nerovnosti, menší a větší než nevztahují.Poskytnete-li implementaci IComparable, musíte obvykle také přepsat Equals tak, že vrátí hodnoty, které jsou konzistentní s CompareTo.Pokud je přepsat Equals a jsou kódování v jazyce, který podporuje operátor přetížení, by také měl hospodářské subjekty, které jsou konzistentní s Equals.

Jak vyřešit narušení

Porušení tohoto pravidla vyřešíte přepsat Equals.Programovací jazyk podporuje-li operátor přetížení, zadejte následující operátory:

  • op_Equality

  • op_Inequality

  • op_LessThan

  • op_GreaterThan

V jazyce C# jsou následující tokeny, které představují tyto operátory: ==,! =, <, a >.

Při potlačení upozornění

Je bezpečné při porušení je způsobeno chybějící operátory a programovací jazyk nepodporuje operátor přetížení, jako v případě rozhraní jazyka Visual Basic potlačí upozornění od tohoto pravidla.Je také bezpečné potlačit varování pro od tohoto pravidla, když je na operátory rovnosti v jiných než op_Equality, pokud zjistíte, že provádění hospodářských nemá smysl v kontextu vaší aplikace.Doporučujeme však vždy nad op_Equality a pokud přepsat Object.Equals == operátor.

Příklad

Následující příklad obsahuje typ, který implementuje správně IComparable.Komentáře v kódu určit metody, které vyhovují různá pravidla, které souvisejí s Equals a IComparable rozhraní.

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, IComparable<RatingInformation>
    {
        public string Rating
        {
            get;
            private set;
        }

        public RatingInformation(string rating)
        {
            if (rating == null)
            {
                throw new ArgumentNullException("rating");
            }
            string v = rating.ToUpper(CultureInfo.InvariantCulture);
            if (v.Length != 1 || string.Compare(v, "C", StringComparison.Ordinal) > 0 || string.Compare(v, "A", StringComparison.Ordinal) < 0)
            {
                throw new ArgumentException("Invalid rating value was specified.", "rating");
            }
            this.Rating = v;
        }

        public int CompareTo(object obj)
        {
            if (obj == null)
            {
                return 1;
            }
            RatingInformation other = obj as RatingInformation; // avoid double casting 
            if (other == null)
            {
                throw new ArgumentException("A RatingInformation object is required for comparison.", "obj");
            }
            return this.CompareTo(other);
        }

        public int CompareTo(RatingInformation other)
        {
            if (object.ReferenceEquals(other, null))
            {
                return 1;
            }
            // Ratings compare opposite to normal string order,  
            // so reverse the value returned by String.CompareTo. 
            return -string.Compare(this.Rating, other.Rating, StringComparison.OrdinalIgnoreCase);
        }

        public static int Compare(RatingInformation left, RatingInformation right)
        {
            if (object.ReferenceEquals(left, right))
            {
                return 0;
            }
            if (object.ReferenceEquals(left, null))
            {
                return -1;
            }
            return left.CompareTo(right);
        }

        // Omitting Equals violates rule: OverrideMethodsOnComparableTypes. 
        public override bool Equals(object obj)
        {
            RatingInformation other = obj as RatingInformation; //avoid double casting 
            if (object.ReferenceEquals(other, null))
            {
                return false;
            }
            return this.CompareTo(other) == 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 left, RatingInformation right)
        {
            if (object.ReferenceEquals(left, null))
            {
                return object.ReferenceEquals(right, null);
            }
            return left.Equals(right);
        }
        public static bool operator !=(RatingInformation left, RatingInformation right)
        {
            return !(left == right);
        }
        public static bool operator <(RatingInformation left, RatingInformation right)
        {
            return (Compare(left, right) < 0);
        }
        public static bool operator >(RatingInformation left, RatingInformation right)
        {
            return (Compare(left, right) > 0);
        }
    }
}

Následující aplikace testuje chování IComparable implementace, která byla dříve zobrazena.

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

Viz také

Referenční dokumentace

IComparable

Object.Equals

Další zdroje

Guidelines for Implementing Equals and the Equality Operator (==)