I have several classes that contain multiple fields. I need to compare them by value, i.e. Two instances of a class are equal if their fields contain the same data. I overridden the GetHashCode and Equals methods for this.
Perhaps these classes contain circular references.
Example: We want to model institutions (e.g. government, sports clubs, whatever). The institution has a name. A Club is an institution that has a name and a list of members. Each member of Person who has a name and a favorite institution. If a member of a certain club has this club as their favorite institution, we have a round link.
But circular links combined with equality of value lead to infinite recursion. Here is a sample code:
interface IInstitution { string Name { get; } } class Club : IInstitution { public string Name { get; set; } public HashSet<Person> Members { get; set; } public override int GetHashCode() { return Name.GetHashCode() + Members.Count; } public override bool Equals(object obj) { Club other = obj as Club; if (other == null) return false; return Name.Equals(other.Name) && Members.SetEquals(other.Members); } } class Person { public string Name { get; set; } public IInstitution FavouriteInstitution { get; set; } public override int GetHashCode() { return Name.GetHashCode(); } public override bool Equals(object obj) { Person other = obj as Person; if (other == null) return false; return Name.Equals(other.Name) && FavouriteInstitution.Equals(other.FavouriteInstitution); } } class Program { public static void Main() { Club c1 = new Club { Name = "myClub", Members = new HashSet<Person>() }; Person p1 = new Person { Name = "Johnny", FavouriteInstitution = c1 } c1.Members.Add(p1); Club c2 = new Club { Name = "myClub", Members = new HashSet<Person>() }; Person p2 = new Person { Name = "Johnny", FavouriteInstitution = c2 } c2.Members.Add(p2); bool c1_and_c2_equal = c1.Equals(c2);
c1_and_c2_equal should return true , and in fact we (people) can see that they are equal in value with a small amount of thinking, without starting into infinite recursion. However, I cannot say how we understand this. But since it is possible, I hope there is a way to solve this problem in the code too!
So the question is: How do I check if values โโare equal without using infinite recursions?
Please note that I need to allow circular references in general, and not just the case above. I will call it 2-circle, since c1 links p1 and p1 links c1 . There may be other n-circles, for example. if club A has a member M whose favorite club B has member N whose favorite club is A That would be 4 laps. Other object models may also allow n-circles with odd numbers n. I am looking for a way to solve all these problems at once, since I will not know in advance what value n can have.
equality c # recursion infinite
Kjara
source share