#c# #inheritance #equals #gethashcode
#c# #наследование #equals #gethashcode
Вопрос:
Я немного смущен поведением Equals и GetHashCode по умолчанию в C #. Допустим, у меня есть два класса, один из которых является производным от другого:
public abstract class Question
{
public string QuestionText
{
get;
set;
}
public override bool Equals(object obj)
{
if (obj is Question)
{
Question q = (Question)obj;
return this.QuestionText.Equals(q.QuestionText);
}
else
{
return false;
}
}
public override int GetHashCode()
{
int hash = 13;
hash = (hash * 7) this.QuestionText.GetHashCode();
return hash;
}
}
public class QuestionTrueFalse : Question
{
public bool CorrectAnswer
{
get;
set;
}
public override bool Equals(object obj)
{
return base.Equals(q);
}
public override int GetHashCode()
{
return base.GetHashCode();
}
}
Производный класс не влияет на то, равен ли один элемент другому, я все еще хочу, чтобы это основывалось просто на свойстве questionText.
Нужно ли мне переопределять Equals и GetHashCode для ссылки на базовую реализацию, как я сделал здесь, или это поведение по умолчанию?
Комментарии:
1. Почему бы вам просто не написать
public override int GetHashCode() { return 91 this.QuestionText.GetHashCode(); }
?
Ответ №1:
Поведение базового класса наследуется наследующими классами. Вам не нужно явно переопределять Equals
и GetHashCode
, если вы не хотите изменить их поведение.
Комментарии:
1. Идеальный ответ. Я просто хотел добавить, что переопределение метода для вызова версии базового типа вообще не влияет на поведение программы (если вы не используете отражение).
Ответ №2:
-
Вы, вероятно, этого не хотите. Почему вы хотели бы иметь отдельные, но равные экземпляры объекта question?
-
Вам, по крайней мере, придется добавить
operator==
иoperator!=
, чтобы избежать неприятных сюрпризов. -
Но нет, вам не нужно переопределять в
QuestionTrueFalse
для вызова базовой реализации. Это предусмотрено.
Стандартный пример (не могу придумать более подходящий для ПК):
Вопрос 1: «Ты все еще бьешь свою жену?» { true, false }
Вопрос 2: «Ты все еще бьешь свою жену?» { true, false, N / A }
Действительно ли они одинаковы?
Ответ №3:
Создать класс, производный от класса, который заботится о Equals и GetHashCode, не так просто. Многие соображения опущены, если просто позволить базовому классу выполнять эту работу.
Вы можете обратиться к этой статье для более глубокого анализа того, как меняется назначение методов Equals и GetHashCode после создания класса: Как переопределить методы Equals и GetHashCode в базовом и производных классах