Ниже использование рефлексии кажется мне лучшим вариантом, учитывая общедоступные свойства, так как при этом вам не нужно беспокоиться о добавлении / удалении свойств (хотя это не очень распространенный сценарий). Я также обнаружил, что это работает лучше (по сравнению с секундомером Diagonistics).
public int getHashCode()
{
PropertyInfo[] theProperties = this.GetType().GetProperties();
int hash = 31;
foreach (PropertyInfo info in theProperties)
{
if (info != null)
{
var value = info.GetValue(this,null);
if(value != null)
unchecked
{
hash = 29 * hash ^ value.GetHashCode();
}
}
}
return hash;
}