How to Use the = Operator, Equals method, ReferenceEquals method, IEquatable interface to compare two objects, referenceequals

Source: Internet
Author: User

How to Use the = Operator, Equals method, ReferenceEquals method, IEquatable interface to compare two objects, referenceequals

"There won't be two identical leaves in the world." This sentence applies to the real world. In the software world, this sentence becomes "the world must have two identical leaves". Otherwise, many things cannot be taken as a result.

 

When two objects are equal, the = Operator is usually used to compare value types and compare values. The instance method Equals and static method Object. referenceEquals compares the reference type with the object address.

 

In actual projects, when two reference type objects are compared, we need to compare all the attributes of the two objects in order to determine whether they are equal. At this time, the IEquatable interface has a chance to present itself. This article mainly includes:

 

  • Use the = Operator to compare whether the value types are equal
  • Instance method Equals compare whether the referenced type address is equal
  • Implement the IEquatable interface to override the instance method Equals ()

 

Use the = Operator to compare whether the value types are equal

    class Program
    {
        static void Main(string[] args)
        {
            ComplexNumber a = new ComplexNumber(){Real = 4.5D, Imaginary = 8.4D};
            ComplexNumber b = new ComplexNumber() { Real = 4.5D, Imaginary = 8.4D };
Console. WriteLine ("{0} is equal to {1 }:{ 2}", a, B, CompareTwoComplexNumbers (a, B ));
            Console.ReadKey();
        }
        static bool CompareTwoComplexNumbers(ComplexNumber a, ComplexNumber b)
        {
            return ((a.Real == b.Real) && (a.Imaginary == b.Imaginary));
        }
    }
    public class ComplexNumber
    {
        public double Real { get; set; }
        public double Imaginary { get; set; }
        public override string ToString()
        {
            return String.Format("{0}{1}{2}i",
                Real,
                Imaginary >= 0 ? "+" : "-",
                Math.Abs(Imaginary));
        }
    }


The = Operator is of course the best choice when comparing the equivalent types such as int, double, DateTime, and struct.

 

Instance method Equals compare whether the referenced type address is equal

    class Program
    {
        static void Main(string[] args)
        {
            Guy darren1 = new Guy("Darren", 37, 100);
            Guy darren2 = darren1;
            Console.WriteLine(Object.ReferenceEquals(darren1,darren2));
            Console.WriteLine(darren1.Equals(darren2));
            Console.WriteLine(Object.ReferenceEquals(null, null));
            darren2 = new Guy("Darren", 37, 100);
            Console.WriteLine(Object.ReferenceEquals(darren1, darren2));
            Console.WriteLine(darren1.Equals(darren2));
            Console.ReadKey();
        }
    }
    public class Guy
    {
        private readonly string name;
        public string Name{get { return name; }}
        private readonly int age;
        public int Age{get { return age; }}
        public int Cash { get; private set; }
        public Guy(string name, int age, int cash)
        {
            this.name = name;
            this.age = age;
            Cash = cash;
        }
        public override string ToString()
        {
Return String. Format ("{0} {1} years old, worth {2}", Name, Age, Cash );
        }
    }

Above, the instance method Equals () and static method Object. ReferenceEquals () are suitable for comparing the reference type and the Object address.


However, what if we want to use the Equals () method to compare the attributes of a reference type object?

 

Implement the IEquatable interface to override the instance method Equals ()

Write a class EquatableGuy derived from Guy, implement the IEquatable <Guy> interface, and override the Equals (Guy other) method of the IEquatable <Guy> interface.

   class Program
    {
        static void Main(string[] args)
        {
            Guy darren1 = new EquatableGuy("Darren", 37, 100);
            Guy darren2 = new EquatableGuy("Darren", 37, 100);
            Console.WriteLine(Object.ReferenceEquals(darren1, darren2)); //False
            Console.WriteLine(darren1.Equals(darren2)); //True
            Console.ReadKey();
        }
    }
    public class Guy
    {
        private readonly string name;
        public string Name{get { return name; }}
        private readonly int age;
        public int Age{get { return age; }}
        public int Cash { get; private set; }
        public Guy(string name, int age, int cash)
        {
            this.name = name;
            this.age = age;
            Cash = cash;
        }
        public override string ToString()
        {
Return String. Format ("{0} {1} years old, worth {2}", Name, Age, Cash );
        }
    }
    public class EquatableGuy : Guy, IEquatable<Guy>
    {
        public EquatableGuy(string name, int age, int cash) : base(name, age, cash){}
        public bool Equals(Guy other)
        {
            if (ReferenceEquals(null, other)) return false;
            if (ReferenceEquals(this, other)) return true;
            return Equals(other.Name, Name) && other.Age == Age && other.Cash == Cash;
        }
        public override bool Equals(object obj)
        {
            if (!(obj is Guy)) return false;
            return Equals((Guy) obj);
        }
        public override int GetHashCode()
        {
            const int prime = 397;
            int result = Age;
            result = (result * prime) ^ (Name != null ? Name.GetHashCode() : 0);
            result = (result * prime) ^ Cash;
            return result;
        }
    }

 

Note the following:
When implementing the IEquatable <Guy> interface, you must override the Equals method of the Object base class, and then call our custom IEquatable <Guy> interface method within the Equals method of the Object base class. In addition, you must override the GetHashCode method of the Object base class. This is what MSDN stipulates.

 

In addition, the advantage of using the IEquatable <Guy> generic interface is to avoid packing and unpacking, because Placeholders are replaced during JIT compilation. If we rewrite the basic Object class method Equals to achieve custom comparison, it is inevitable that there will be packing and unpacking, affecting the comparison performance.


If we use the = Operator to compare the referenced objects, is it equal? We can use the rewrite operator.

 

Let's write another EquatableGuy subclass EquatableGuyWithOverload and rewrite the = Operator.

   class Program
    {
        static void Main(string[] args)
        {
            var darren1 = new EquatableGuyWithOverload("Darren", 37, 100);
            var darren2 = new EquatableGuyWithOverload("Darren", 37, 100);
            Console.WriteLine(Object.ReferenceEquals(darren1, darren2)); //False
            Console.WriteLine(darren1 == darren2); //True
            Console.ReadKey();
        }
    }
    public class EquatableGuyWithOverload : EquatableGuy
    {
        public EquatableGuyWithOverload(string name, int age, int cash) : base(name, age, cash){}
        public static bool operator ==(EquatableGuyWithOverload left, EquatableGuyWithOverload right)
        {
            if (Object.ReferenceEquals(left, null)) return false;
            else return left.Equals(right);
        }
        public static bool operator !=(EquatableGuyWithOverload left, EquatableGuyWithOverload right)
        {
            return !(left == right);
        }
        public override bool Equals(object obj)
        {
            return base.Equals(obj);
        }
        public override int GetHashCode()
        {
            return base.GetHashCode();
        }
    }

 

Above, the subclass EquatableGuyWithOverload overwrites the = Operator. Since its parent class EquatableGuy has overwritten the Equals method of the base class Object, it can be called directly here.

 

Summary: Generally, the = Operator is used to compare value type objects, and the instance method Equals or static method Object is used. referenceEquals compares the addresses of referenced objects. to customize the comparison logic, you can consider implementing the IEquatable <> generic interface to avoid packing and unpacking.

 

References:

It also fails to prevent packing in the end.
Understanding C #: Equality, IEquatable, and Equals ()
Questions about the results of the ReferenceEquals method of two value types in c #

Note that Object. ReferenceEquals is used to determine whether two referenced variables reference the same instance.
Int. ReferenceEquals actually inherits Object. ReferenceEquals
The method is defined as follows:
Public static bool ReferenceEquals (object objA, object objB );

Both objA and objB refer to object types.
The result of passing in the "i1", "i2", "1" value type variables is
Binning objA and objB are packed into a new reference type instance, which naturally does not reference the same, so always returns False

C # What is the difference between objectReferenceEquals (obj1, obj2) and "=?

First, Object. ReferenceEquals (), Equaql, =, can be used to compare two objects
1. Object. Reference is a static method and cannot be rewritten. Equals is a virtual method and can be rewritten. ==, it can be reloaded by operators.
2. When comparing two objects of a type, if the equals method and the = operator are not overwritten in this class, the three conditions will get the same result.
3. If the comparison type is to overwrite the equals and = operators, the possible results will be different. This depends on the method body to be overwritten and the method body to be reloaded =.
Public override bool Equals (Person obj)
{
Return 1 = 1;

}
Public static bool operator = (Person p1, Person p2)
{
Return p1.Age = p2.Age;

}
// In this case, if you call the Equals method to compare two Peson objects, true will be obtained, and false will be obtained for Referernce. If Age of p1 and p2 is the same, true will be obtained.

Finally, if two objects in a class get different results by calling the above three methods, the class must overwrite the equals method or both overload the = Operator (and must be reloaded at the same time! = Operator)

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.