Back in the days, we had to use XOR (^) or other cumbersome approaches, overriding GetHashCode function. Something like this:
public class Client : IEquatable<Client>
{
public Guid Id { get; set; }
public string Code { get; set; }
public string Country { get; set; }
public bool Equals(Client other) => this.Code == other.Code && this.Country == other.Country;
public override int GetHashCode() => this.Code.GetHashCode() ^ this.Country.GetHashCode();
}
Recently I found a fancy way to build an elegant GetHashCode implementation. The general idea is based on the fact that a tuple of required properties is being built. Then just a hash code of that tuple is being returned:
public override int GetHashCode() => (this.Code, this.Country).GetHashCode();
The whole class:
public class Client : IEquatable<Client>
{
public Guid Id { get; set; }
public string Code { get; set; }
public string Country { get; set; }
public bool Equals(Client other) => this.Code == other.Code && this.Country == other.Country;
public override int GetHashCode() => (this.Code, this.Country).GetHashCode();
}