If we have a class that contains properties/fields of other reference types, how would a proper and elegant equality check be performed?
For example, MainClass contains properties of SubClassA and SubClassB. We can assume that all of these classes override object.Equals with the same implementation, what would that be?
I came up with the following which doesn't look very nice. My logic is as follows:
We cannot use
Equalsdirectly on the reference types because they can be null, so we first check if only one of them is null, which leads to inequality.Then, if both have a value, make sure the value is equal.
We can omit the check that they are both null as it leads to equality.
class MainClass { SubClassA A {get; set;} SubClassB B {get; set;} int someint {get; set;} public override bool Equals(object obj) { MainClass other = obj as MainClass; if (other is null) return false; // First check if only one of the As is null. if (A is null ^ other.A is null) { return false; } // Then check if both have a value that the value is equal. else if (A != null && other.A != null && !A.Equals(other.A)) { return false; } // Case where As are both null is omitted as it leads to equality. // Same principle here and for any other reference types... if (B is null ^ other.B is null) { return false; } else if (B != null && other.B != null && !B.Equals(other.B)) { return false; } // Value types can go down here. return someint.Equals(other.someint); } } class SubClassA { // some properties } class SubClassB { // some properties }
You don't need to reinvent the wheel. .NET has an
EqualityComparer<T>.Defaultproperty that can handle most of equality comparison situations (including yours). Read the remark section for more details.Note, please read this article: System.Object.Equals method if you want to override
Equals. In summary, you'd better override theGetHashCodemethod and implement theIEquatable<T>interface too.