ca2224: يساوي التجاوز تشغيل التحميل الزائد يساوي عامل التشغيل

TypeName

OverrideEqualsOnOverloadingOperatorEquals

CheckId

ca2224

Category

Microsoft.Usage

تعطيل تغيير

غير فاصلة

السبب

يطبق عامل مساواة نوعا عاماً، ولكن هل لا يمنع Object.Equals.

وصف القاعدة

عامل تشغيل مساواة هو مخصصة لتكون طريقة ملائمة لبناء للوصول إلى الوظيفة في Equalsالأسلوب. إذا قمت بتطبيق operaإلىr مساواة، يجب أن يكون المنطق مماثلة إلى من Equals.

صدور المحول البرمجي C# تحذير في حالة انتهاك تعليمات برمجية هذه قاعدة.

كيف إلى الإصلاح انتهاكات

إلى إصلاح انتهاكا لهذه قاعدة، عليك أما إزالة تطبيق operaإلىr مساواة، أو يمنع Equalsويكون طريقتين إرجاع نفس قيم. إذا كان عامل التشغيل مساواة لا تقدم سلوك غير متناسقة، فيمكنك تصحيح الانتهاك من خلال توفير تطبيق Equalsيستدعي Equalsالأسلوب في فئة. الأساسية

عند إلى منع التحذيرات

أمان لمنع ظهور تحذير من هذه قاعدة إذا كان عامل التشغيل مساواة بإرجاع نفس القيمة مثل تطبيق الموروثة Equals. يتضمن مقطع مثال على نوع أمان يمكن منع ظهور تحذير من هذه قاعدة.

أمثلة على ملفات تعريف مساواة غير متسقة

الوصف

يلي مثال يظهر نوع ذو ملفات تعريف مساواة غير متناسقة. BadPointيتغير معنى المساواة بواسطة توفير تطبيق مخصص لعامل مساواة، ولكن لا يتجاوزEqualsحيث أنه يعمل بالمثل.

الرمز

using System;

namespace UsageLibrary
{   
    public class BadPoint
    {
        private int x,y, id;
        private static int NextId;

        static BadPoint()
        {
            NextId = -1;
        }
        public BadPoint(int x, int y)
        {
            this.x = x;
            this.y = y;
            id = ++(BadPoint.NextId); 
        }

        public override string ToString()
        {
            return String.Format("([{0}] {1},{2})",id,x,y);
        }

        public int X {get {return x;}}

        public int Y {get {return x;}}
        public int Id {get {return id;}}

        public override int GetHashCode()
        {
            return id;
        }
        // Violates rule: OverrideEqualsOnOverridingOperatorEquals.

        // BadPoint redefines the equality operator to ignore the id value.
        // This is different from how the inherited implementation of 
        // System.Object.Equals behaves for value types. 
        // It is not safe to exclude the violation for this type. 
        public static bool operator== (BadPoint p1, BadPoint p2)
        {
            return ((p1.x == p2.x) && (p1.y == p2.y));
        }
        // The C# compiler and rule OperatorsShouldHaveSymmetricalOverloads require this.
        public static bool operator!= (BadPoint p1, BadPoint p2)
        {
            return !(p1 == p2);
        }
    }
}

مثال

اختبار تعليمات برمجية التالية سلوك BadPoint.

using System;

namespace UsageLibrary
{   
    public class TestBadPoint
    {
        public static void Main()
        {
            BadPoint a = new BadPoint(1,1);
            BadPoint b = new BadPoint(2,2);
            BadPoint a1 = a;
            BadPoint bcopy = new BadPoint(2,2);

            Console.WriteLine("a =  {0} and b = {1} are equal? {2}", a, b, a.Equals(b)? "Yes":"No");
            Console.WriteLine("a == b ? {0}", a == b ? "Yes":"No");
            Console.WriteLine("a1 and a are equal? {0}", a1.Equals(a)? "Yes":"No");
            Console.WriteLine("a1 == a ? {0}", a1 == a ? "Yes":"No");

            // This test demonstrates the inconsistent behavior of == and Object.Equals.
            Console.WriteLine("b and bcopy are equal ? {0}", bcopy.Equals(b)? "Yes":"No");
            Console.WriteLine("b == bcopy ? {0}", b == bcopy ? "Yes":"No");
        }
    }
}

ينتج هذا المثال الإخراج التالي:

a =  ([0] 1,1) and b = ([1] 2,2) are equal? No a == b ? No a1 and a are equal? Yes a1 == a ? Yes b and bcopy are equal ? No b == bcopy ? Yes 

يظهر المثال التالي هو نوع تقنيا انتهاك هذه قاعدة، ولكن لا تتصرف على نحو غير متناسقة.

using System;

namespace UsageLibrary
{
    public struct GoodPoint
    {
        private int x,y;

        public GoodPoint(int x, int y)
        {
            this.x = x;
            this.y = y;
        }

        public override string ToString()
        {
            return String.Format("({0},{1})",x,y);
        }

        public int X {get {return x;}}

        public int Y {get {return x;}}

        // Violates rule: OverrideEqualsOnOverridingOperatorEquals,
        // but does not change the meaning of equality;
        //  the violation can be excluded.

        public static bool operator== (GoodPoint px, GoodPoint py)
        {
            return px.Equals(py);
        }

        // The C# compiler and rule OperatorsShouldHaveSymmetricalOverloads require this.
        public static bool operator!= (GoodPoint px, GoodPoint py)
        {
            return !(px.Equals(py));
        }
    }
}

اختبار تعليمات برمجية التالية سلوك GoodPoint.

using System;

namespace UsageLibrary
{ 
    public class TestGoodPoint
    {
        public static void Main()
        {
            GoodPoint a = new GoodPoint(1,1);
            GoodPoint b = new GoodPoint(2,2);
            GoodPoint a1 = a;
            GoodPoint bcopy = new GoodPoint(2,2);

            Console.WriteLine("a =  {0} and b = {1} are equal? {2}", a, b, a.Equals(b)? "Yes":"No");
            Console.WriteLine("a == b ? {0}", a == b ? "Yes":"No");
            Console.WriteLine("a1 and a are equal? {0}", a1.Equals(a)? "Yes":"No");
            Console.WriteLine("a1 == a ? {0}", a1 == a ? "Yes":"No");

            // This test demonstrates the consistent behavior of == and Object.Equals.
            Console.WriteLine("b and bcopy are equal ? {0}", bcopy.Equals(b)? "Yes":"No");
            Console.WriteLine("b == bcopy ? {0}", b == bcopy ? "Yes":"No");
        }
    }
}

ينتج هذا المثال الإخراج التالي:

a =  (1,1) and b = (2,2) are equal? No a == b ? No a1 and a are equal? Yes a1 == a ? Yes b and bcopy are equal ? Yes b == bcopy ? Yes 

يعمل المثال التالي على إصلاح الخرق بتجاوز Object.Equals.

using System; 

namespace Samples
{    
    public class Point    
    {        
        private readonly int _X;        
        private readonly int _Y;         

        public Point(int x, int y)        
        {            
            _X = x;            
            _Y = y;        
        }         

        public int X        
        {            
            get { return _X; }        
        }         

        public int Y        
        {            
            get { return _Y; }        
        }         

        public override int GetHashCode()        
        {            
            return _X ^ _Y;        
        }         

        public override bool Equals(object obj)        
        {            
            if (obj == null)                
                return false;             

            if (GetType() != obj.GetType())                
                return false;             

            Point point = (Point)obj;             

            if (_X != point.X)                
                return false;             

            return _Y == point.Y;        
        }         

        public static bool operator ==(Point point1, Point point2)        
        {            
            return Object.Equals(point1, point2);        
        }         

        public static bool operator !=(Point point1, Point point2)        
        {            
            return !Object.Equals(point1, point2);        
        }    
    }
}

يعمل المثال التالي على إصلاح الخرق بتجاوز ValueTypeEquals().

using System; 

namespace Samples
{    
    public struct Point : IEquatable<Point>    
    {        
        private readonly int _X;        
        private readonly int _Y;         

        public Point(int x, int y)        
        {            
            _X = x;            
            _Y = y;        
        }         

        public int X        
        {            
            get { return _X; }        
        }         

        public int Y        
        {            
            get { return _Y; }        
        }         

        public override int GetHashCode()        
        {            
            return _X ^ _Y;        
        }         

        public override bool Equals(object obj)        
        {            
            if (!(obj is Point))                
                return false;             

            return Equals((Point)obj);        
        }         

        public bool Equals(Point other)        
        {            
            if (_X != other._X)                
                return false;             

            return _Y == other._Y;        
        }         

        public static bool operator ==(Point point1, Point point2)        
        {            
            return point1.Equals(point2);        
        }         

        public static bool operator !=(Point point1, Point point2)        
        {            
            return !point1.Equals(point2);        
        }    
    }
}

مثال للفئة

الوصف

يلي مثال يظهر فئة (نوع مرجع) يخالف هذه قاعدة.

الرمز

using System; 

namespace Samples
{    
    // Violates this rule    
    public class Point    
    {        
        private readonly int _X;        
        private readonly int _Y;         

        public Point(int x, int y)        
        {            
            _X = x;            
            _Y = y;        
        }         

        public int X        
        {            
            get { return _X; }        
        }         

        public int Y        
        {            
            get { return _Y; }        
        }         

        public override int GetHashCode()        
        {            
            return _X ^ _Y;        
        }             

        public static bool operator ==(Point point1, Point point2)        
        {            
            if (point1 == null || point2 == null)                
                return false;             

            if (point1.GetType() != point2.GetType())                
                return false;             

            if (point1._X != point2._X)                    
                return false;             

            return point1._Y == point2._Y;        
        }         

        public static bool operator !=(Point point1, Point point2)        
        {            
            return !(point1 == point2);        
        }    
    }
}

مثال لبنية

الوصف

يلي مثال عرض بنية (نوع القيمة) يخالف هذه قاعدة.

الرمز

using System; 

namespace Samples
{    
    // Violates this rule    
    public struct Point    
    {        
        private readonly int _X;        
        private readonly int _Y;         

        public Point(int x, int y)        
        {            
            _X = x;            
            _Y = y;        
        }         

        public int X        
        {            
            get { return _X; }        
        }         

        public int Y        
        {            
            get { return _Y; }        
        }         

        public override int GetHashCode()        
        {            
            return _X ^ _Y;        
        }         

        public static bool operator ==(Point point1, Point point2)        
        {            
            if (point1._X != point2._X)                
                return false;                        

            return point1._Y == point2._Y;        
        }         

        public static bool operator !=(Point point1, Point point2)        
        {            
            return !(point1 == point2);        
        }    
    }
}

القواعد ذات الصلة

حفظ معلومات الرمز مع إنشاء تشكيل جانبي لملفات بيانات ca2116:

CA2223: Members should differ by more than return type

الوحدات النمطية لعرض-أخذ عينات ca1020:

ca2218: يمنع GetHashCode تشغيل يمنع يساوي

ca2231: يساوي عامل التحميل الزائد تشغيل تجاوز ValueType.Equals