Ответ 1
Я бы избегал делать это просто на том основании, что он создает пучок строк бессмысленно - хотя пункт Kosi2801 о том, чтобы сделать столкновение простым, также имеет значение. (Я подозреваю, что на самом деле не создаст много столкновений из-за природы полей, но...)
Я хотел бы использовать алгоритм "простой и простой в использовании", который я ранее использовал в этом ответе (спасибо за то, что посмотрел на него:) - и который указан в "Эффективной Java", как вы сказали. В этом случае это будет выглядеть следующим образом:
public int GetHashCode()
{
int hash = 17;
// Suitable nullity checks etc, of course :)
hash = hash * 23 + StreetAddress.GetHashCode();
hash = hash * 23 + RuralRoute.GetHashCode();
hash = hash * 23 + City.GetHashCode();
hash = hash * 23 + Province.GetHashCode();
hash = hash * 23 + Country.GetHashCode();
hash = hash * 23 + PostalCode.GetHashCode();
return hash;
}
Это небезопасно, конечно. Если вы используете С# 3, вы можете рассмотреть метод расширения:
public static int GetNullSafeHashCode<T>(this T value) where T : class
{
return value == null ? 1 : value.GetHashCode();
}
Затем вы можете использовать:
public int GetHashCode()
{
int hash = 17;
// Suitable nullity checks etc, of course :)
hash = hash * 23 + StreetAddress.GetNullSafeHashCode();
hash = hash * 23 + RuralRoute.GetNullSafeHashCode();
hash = hash * 23 + City.GetNullSafeHashCode();
hash = hash * 23 + Province.GetNullSafeHashCode();
hash = hash * 23 + Country.GetNullSafeHashCode();
hash = hash * 23 + PostalCode.GetNullSafeHashCode();
return hash;
}
Вы можете создать утилиту метода массива параметров, чтобы сделать это еще проще:
public static int GetHashCode(params object[] values)
{
int hash = 17;
foreach (object value in values)
{
hash = hash * 23 + value.GetNullSafeHashCode();
}
return hash;
}
и назовите его с помощью:
public int GetHashCode()
{
return HashHelpers.GetHashCode(StreetAddress, RuralRoute, City,
Province, Country, PostalCode);
}
В большинстве типов присутствуют примитивы, так что они будут выполнять бокс несколько ненужно, но в этом случае у вас будут только ссылки. Конечно, вы в конечном итоге создадите массив без необходимости, но знаете, что они говорят о преждевременной оптимизации...