В моем проекте на C # есть сложный класс, в котором я хочу проводить тесты на равенство. Это не тривиальный класс; он содержит различные скалярные свойства, а также ссылки на другие объекты и коллекции (например, IDictionary). Что бы это ни стоило, мой класс запечатан.
Чтобы включить оптимизацию производительности в других частях моей системы (оптимизация, позволяющая избежать дорогостоящего обхода сети), мне нужно иметь возможность сравнивать экземпляры этих объектов друг с другом для равенства & ndash; кроме встроенного ссылочного равенства & ndash; и поэтому я переопределяю метод экземпляра Object.Equals (). Однако теперь, когда я это сделал, в FxCop анализа кода Visual Studio 2008. a.k.a, который я оставляю включенным по умолчанию, выдается следующее предупреждение:
предупреждение: CA2218: Microsoft.Usage: начиная с MySuperDuperClass
переопределяет Equals, также следует переопределить GetHashCode.
Мне кажется, я понимаю обоснование этого предупреждения: Если Я собираюсь использовать в коллекции такие объекты, как ключ , хеш-код это важно. то есть см. этот вопрос . Однако я не собираюсь использовать эти объекты в качестве ключа в коллекции. Когда-либо.
Чувствуя себя оправданным для подавления предупреждения, я посмотрел код CA2218 в документации MSDN , чтобы получить полное имя предупреждения, чтобы я мог применить атрибут SuppressMessage
к своему классу следующим образом:
[SuppressMessage("Microsoft.Naming",
"CA2218:OverrideGetHashCodeOnOverridingEquals",
Justification="This class is not to be used as key in a hashtable.")]
Однако, читая дальше, я заметил следующее:
Как исправить нарушения
Чтобы исправить нарушение этого правила,
обеспечить реализацию
GetHashCode. Для пары объектов
того же типа, вы должны убедиться, что
реализация возвращает то же самое
значение, если ваша реализация равно
возвращает true для пары.
Когда следует подавлять предупреждения
-----> Не подавлять предупреждение от этого
правило. [стрелка и акцент мой]
Итак, я хотел бы знать: Почему бы мне не подавить это предупреждение, как я планировал? Разве мой случай не требует подавления? Я не хочу кодировать реализацию GetHashCode () для этого объекта, который никогда не будет вызываться, так как мой объект никогда не будет ключом в коллекции. Если бы я хотел быть педантичным, а не подавлять, было бы разумнее переопределить GetHashCode () с реализацией, которая выдает исключение NotImplementedException?
Обновление: Я только что снова посмотрел эту тему в хорошей книге Билла Вагнера
Эффективное C # , и он заявляет в "Item 10: Understapits GetHashCode ()":
Если вы определяете тип, который не будет
когда-либо использоваться в качестве ключа в
контейнер, это не имеет значения. Типы
которые представляют элементы управления окнами, веб
элементы управления страницей или соединения с базой данных
вряд ли будут использоваться в качестве ключей в
коллекция. В этих случаях делайте
ничего такого. Все ссылочные типы будут
иметь правильный хеш-код, даже
если это очень неэффективно. [...] В
большинство типов, которые вы создаете, лучший
подход заключается в том, чтобы избежать существования
GetHashCode () полностью.
... вот откуда у меня возникла мысль, что мне не нужно беспокоиться о GetHashCode () всегда.