none
Question about equals in Operator Overloading RRS feed

  • Question

  • Hello,

    What is compare exactly in two object POne and PTwo?

    I can't understand well because each object of Point have two property (XPoint and YPoint) for own. The result of the below code is True.

    
    
    using System;
    
    
    namespace P960929_P1
    {
        class Point
        {
            public int XPoint { get; set; }
            public int YPoint { get; set; }
            string Name;
            public Point(int X , int Y, string name)
            {
                XPoint = X;
                YPoint = Y;
                Name = name;
            }
            public override string ToString() => $"[{XPoint} , {YPoint}]";
            public override bool Equals(object obj) => obj.ToString() == this.ToString();
            public static bool operator ==(Point P1, Point P2) => P1.Equals(P2);
            public static bool operator !=(Point P1, Point P2) => !P1.Equals(P2);
    
        }
        class Program
        {
            static void Main(string[] args)
            {
                Point POne = new Point(10, 10,"TEST");
                Point PTwo = new Point(10, 10,"OK");
    
                Console.WriteLine(POne == PTwo);
            
    
                Console.ReadKey();
            }
        }
    }




    • Edited by Arash_89 Wednesday, December 20, 2017 4:06 PM
    Wednesday, December 20, 2017 4:01 PM

Answers

  • Well, the code in question has a rather terrible implementation of Equals.  Basically the code converts both points to strings then compares the strings. This will get the job done, but is unnecessarily slow.  By converting both objects to strings, it is possible to perform a single comparison instead of comparing both the XPoints and YPoints.

    A decent implementation would simply have compared the XPoint and YPoint of each object.

            public override bool Equals(object obj) => XPoint==obj.XPoint && YPoint==obj.YPoint;

    The overloads simply delegate their implementation to the implementation of Equals.  That part of the implementation is fine.

    • Proposed as answer by Fei HuModerator Thursday, December 21, 2017 2:02 AM
    • Marked as answer by Arash_89 Wednesday, December 27, 2017 8:54 AM
    Wednesday, December 20, 2017 4:10 PM
  • I would go even further and say the implementation of Equals is wrong. Based upon the original implementation, the following would be true but it is wrong.

    var someValue = "[10, 20]";
    
    var point = new Point(10, 20, "Point1");
    
    //True, but wrong
    var equals = point.Equals(someValue);
    
    var point2 = new Point(10, 20, "Point2");
    
    //True, but wrong
    var equals2 = point.Equals(point2);
    

    Implementing Equals is not trivial and for a class it is almost always wrong to do so. Ref types (aka C# classes) should follow the standard reference semantics. It is exceedingly rare not to and Point isn't one of those exceptions. At a minimum the Point class should be a struct. Then implementing equality makes more sense and can be more easily done. How to properly implement equality is explained here.

    https://msdn.microsoft.com/en-us/library/336aedhh(v=vs.100).aspx

    https://docs.microsoft.com/en-us/dotnet/standard/design-guidelines/equality-operators


    Michael Taylor http://www.michaeltaylorp3.net

    • Marked as answer by Arash_89 Wednesday, December 27, 2017 8:54 AM
    Wednesday, December 20, 2017 6:18 PM
    Moderator
  • Hello Arash_89,

    Is there any update or any other assistance I could provide? In you code you have overrided the "ToString","Equals" method and "==","!=" operator.

    When you invoke "==" the process should be like the below steps.

    invoke the "==" operator >> invoke Equals method >> invoke ToString method

    And if you have any concerns, please do not hesitate to let us know.

    Thank you for your understanding and patience!

    Best regards,

    Neil Hu


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    • Marked as answer by Arash_89 Wednesday, December 27, 2017 8:54 AM
    • Edited by Fei HuModerator Wednesday, December 27, 2017 8:55 AM
    Wednesday, December 27, 2017 8:25 AM
    Moderator

All replies

  • Well, the code in question has a rather terrible implementation of Equals.  Basically the code converts both points to strings then compares the strings. This will get the job done, but is unnecessarily slow.  By converting both objects to strings, it is possible to perform a single comparison instead of comparing both the XPoints and YPoints.

    A decent implementation would simply have compared the XPoint and YPoint of each object.

            public override bool Equals(object obj) => XPoint==obj.XPoint && YPoint==obj.YPoint;

    The overloads simply delegate their implementation to the implementation of Equals.  That part of the implementation is fine.

    • Proposed as answer by Fei HuModerator Thursday, December 21, 2017 2:02 AM
    • Marked as answer by Arash_89 Wednesday, December 27, 2017 8:54 AM
    Wednesday, December 20, 2017 4:10 PM
  • I would go even further and say the implementation of Equals is wrong. Based upon the original implementation, the following would be true but it is wrong.

    var someValue = "[10, 20]";
    
    var point = new Point(10, 20, "Point1");
    
    //True, but wrong
    var equals = point.Equals(someValue);
    
    var point2 = new Point(10, 20, "Point2");
    
    //True, but wrong
    var equals2 = point.Equals(point2);
    

    Implementing Equals is not trivial and for a class it is almost always wrong to do so. Ref types (aka C# classes) should follow the standard reference semantics. It is exceedingly rare not to and Point isn't one of those exceptions. At a minimum the Point class should be a struct. Then implementing equality makes more sense and can be more easily done. How to properly implement equality is explained here.

    https://msdn.microsoft.com/en-us/library/336aedhh(v=vs.100).aspx

    https://docs.microsoft.com/en-us/dotnet/standard/design-guidelines/equality-operators


    Michael Taylor http://www.michaeltaylorp3.net

    • Marked as answer by Arash_89 Wednesday, December 27, 2017 8:54 AM
    Wednesday, December 20, 2017 6:18 PM
    Moderator
  • Hello Arash_89,

    Is there any update or any other assistance I could provide? In you code you have overrided the "ToString","Equals" method and "==","!=" operator.

    When you invoke "==" the process should be like the below steps.

    invoke the "==" operator >> invoke Equals method >> invoke ToString method

    And if you have any concerns, please do not hesitate to let us know.

    Thank you for your understanding and patience!

    Best regards,

    Neil Hu


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    • Marked as answer by Arash_89 Wednesday, December 27, 2017 8:54 AM
    • Edited by Fei HuModerator Wednesday, December 27, 2017 8:55 AM
    Wednesday, December 27, 2017 8:25 AM
    Moderator