The implementation of the Equals method is intended to perform a test for equality with another object of type T, the same type as the current object. The Equals method is called in the following circumstances:
-
When the Equals method is called and the other parameter represents a strongly-typed object of type T. (If other is of type Object, the base Object.Equals(Object) method is called. Of the two methods, IEquatable<T>.Equals offers slightly better performance.)
-
When the search methods of a number of generic collection objects are called. Some of these types and their methods include the following:
-
Some of the generic overloads of the BinarySearch method.
-
The search methods of the List<T> class, including List<T>.Contains(T), List<T>.IndexOf, List<T>.LastIndexOf, and List<T>.Remove.
-
The search methods of the Dictionary<TKey, TValue> class, including ContainsKey and Remove.
-
The search methods of the generic LinkedList<T> class, including LinkedList<T>.Contains and Remove.
-
In other words, to handle the possibility that objects of a class will be stored in an array or a generic collection object, it is a good idea to implement IEquatable<T> so that the object can be easily identified and manipulated.
两点注意:
1)如果对象需要存储在集合类中,编写这些类时要考虑实现IEquatable<T>.Equals方法以实现判等,实现IComparable<T>接口以实现排序;
2) 集合类中的某些方法例如LinkedList.Find 方法等要利用对象的Equals方法来判断是否相等。
Sample: 观察对象类的Equals, GetHashCode以及operator override
using System; using System.Collections.Generic; using System.Text.RegularExpressions; public class Person : IEquatable<Person> { private string uniqueSsn; private string lName; public Person(string lastName, string ssn) { this.SSN = ssn; this.LastName = lastName; } public string SSN { get { return this.uniqueSsn; } set { if (Regex.IsMatch(value, @"\d{9}")) uniqueSsn = String.Format("{0}-(1}-{2}", value.Substring(0, 3), value.Substring(3, 2), value.Substring(5, 4)); else if (Regex.IsMatch(value, @"\d{3}-\d{2}-\d{4}")) uniqueSsn = value; else throw new FormatException("The social security number has an invalid format."); } } public string LastName { get { return this.lName; } set { if (String.IsNullOrEmpty(value)) throw new ArgumentException("The last name cannot be null or empty."); else this.lName = value; } } public bool Equals(Person other) { if (other == null) return false; if (this.uniqueSsn == other.SSN) return true; else return false; } public override bool Equals(Object obj) { if (obj == null) return false; Person personObj = obj as Person; if (personObj == null) return false; else return Equals(personObj); } public override int GetHashCode() { return this.SSN.GetHashCode(); } public static bool operator == (Person person1, Person person2) { if ((object)person1 == null || ((object)person2) == null) return Object.Equals(person1, person2); return person1.Equals(person2); } public static bool operator != (Person person1, Person person2) { if (person1 == null || person2 == null) return ! Object.Equals(person1, person2); return ! (person1.Equals(person2)); } }
Test :
public class TestIEquatable { public static void Main() { // Create a Person object for each job applicant. Person applicant1 = new Person("Jones", "099-29-4999"); Person applicant2 = new Person("Jones", "199-29-3999"); Person applicant3 = new Person("Jones", "299-49-6999"); // Add applicants to a List object. List<Person> applicants = new List<Person>(); applicants.Add(applicant1); applicants.Add(applicant2); applicants.Add(applicant3); // Create a Person object for the final candidate. Person candidate = new Person("Jones", "199-29-3999"); if (applicants.Contains(candidate)) Console.WriteLine("Found {0} (SSN {1}).", candidate.LastName, candidate.SSN); else Console.WriteLine("Applicant {0} not found.", candidate.SSN); // Call the shared inherited Equals(Object, Object) method. // It will in turn call the IEquatable(Of T).Equals implementation. Console.WriteLine("{0}({1}) already on file: {2}.", applicant2.LastName, applicant2.SSN, Person.Equals(applicant2, candidate)); } } // The example displays the following output: // Found Jones (SSN 199-29-3999). // Jones(199-29-3999) already on file: True.