Нечитанные поля, на которые ссылаются в GetHashCode()

Начнем с переопределения понятий, и я переопределяю методы Equals и GetHashCode.

В первую очередь я придумал этот "очень простой код":

internal class Person
    {
        public string name;

        public int age;

        public string lname;

        public Person(string name, int age, string lname)
        {
            this.name = name;
            this.age = age;
            this.lname = lname;
        }

        public override bool Equals(object obj)
        {
            var person = obj as Person;
            if (person != null)
            {
                return person.age == this.age && person.name == this.name && person.lname == this.lname;
            }

            return false;
        }

        public override int GetHashCode()
        {
            return this.age.GetHashCode() * this.name.GetHashCode() * this.lname.GetHashCode();
        }
    }

Пока это отлично работает, мой "со-разработчик" Mr.Resharper дал мне несколько советов:

  • Неверные поля, на которые ссылаются в GetHashCode(). Предложения пришли в эту строку кода:

return this.age.GetHashCode() * this.name.GetHashCode() * this.lname.GetHashCode();

  1. Следует ли использовать GetHashCode только для свойств?

Ответы

Ответ 1

Подводя итог обсуждению в комментариях:

Hashing предназначен для предоставления значения, которое не изменяется для данного объекта, независимо от того, что с ним происходит, поэтому лучше всего зависеть только от полей readonly в методе GetHashCode.

Во-первых, я бы предложил сделать поле name и lname только для чтения, потому что они, вероятно, не изменяются в вашем сценарии использования.

Что касается age, это то, что меняется регулярно, поэтому, вероятно, лучше всего хранить DateTime для даты рождения, которая никогда не изменяется. Тогда вы можете сделать это и только для чтения.