2013-03-26 4 views
-1

Меня интересует ваше мнение относительно проблемы, возникшей при реализации небольшой библиотеки для написания интеграционных/системных тестов на C#. Библиотека состоит из 2 части: тест Authoring API и тестовый Runtime API. Писатель теста использует авторский API для создания прототипов плана тестирования. Время выполнения может занять прототип и создать представление прототипа и выполнить его.Как указать, что экземпляры некоторых классов не должны использоваться в качестве ключей словаря?

Чтобы проверить класс с именем RuntimeTestPlanBuilder, мне пришлось переопределить метод Equals во всех классах объектных моделей времени исполнения. Это привело к ситуации, когда я должен переопределить метод GetHashCode. Реализация GetHashCode для некоторых классов объектной модели среды выполнения была простой. Поскольку некоторые классы в модели времени выполнения являются контейнерами, реализующими GetHashCode для них, было жестким и даже невозможным (поскольку среда выполнения может добавлять элементы в контейнер, хэш-код не может быть вычислен в O (1), например).

В результате я обнаружил, что мне интересно, как запретить пользователям контейнеров помещать их в словарь в качестве ключей. Решение, которое я выбрал, - это переопределить метод GetHashCode и выбросить исключение. Я не удовлетворен этим решением, так как он будет работать только во время выполнения. Кроме того, я удивляюсь, почему дизайнеры .Net Framework решили поместить метод GetHashCode в класс Object. Я думаю, что это решение привело к моей ситуации, так как я не могу пометить свои контейнеры как незаменимые словарные ключи в отличной форме.

Лучшим решением (для дизайнеров .Net Framework) могло быть определение интерфейса с именем IHashable с помощью двух методов: Equals и GetHashCode и принудительного применения интерфейса с ограничением по типу универсального словаря. Таким образом, мы можем обеспечить во время компиляции, что ключи реализуют Equals и GetHashCode. Кроме того, легко понять, что классы, которые не реализуют этот интерфейс, не должны использоваться в качестве словарных клавиш.

Мой вопрос: можете ли вы предложить лучшее решение (не исключающее исключения из GetHashCode), чтобы указать, что экземпляры некоторых классов не должны использоваться в качестве ключей словаря?

Благодаря

+0

Как вы реализуете метод Equals() в классах проблем? Реализация GetHashCode() не должна быть сложнее, чем реализация Equals(). –

+0

В принципе, 2 контейнера равны, если они имеют одинаковое количество элементов, и все предметы в тех же местах равны. – Ikaso

+0

@PieterGeerkens - попытайтесь представить мой вопрос не в указанном контексте, а в более широком контексте - как пометить некоторые классы как неправомерные ключи словаря? – Ikaso

ответ

0

Объект предполагается реализовать пять методов и GetHashCode является одним из них.
Нельзя быть уверенным, что только текущее или будущее использование GetHashCode для словарного ключа.

Единственное правило: два равных объекта должны иметь один и тот же GetHashCode.
Но тот же GetHashCode не означает, что два объекта равны.

Вы можете использовать константу (1) для GetHashCode или количество элементов в контейнере.
Или увидеть этот ответ от тарелочек

is-it-possible-to-combine-hash-codes-for-private-members-to-generate-a-new-hash

0

Как правило, два объект должен сообщать о себе только как равном, если они есть и всегда будут эквивалентны; изменяемые объекты, включая изменчивые коллекции, должны в общем случае считаться равными друг другу. Неизменяемые коллекции могут эффективно реализовывать GetHashCode путем кэширования значений их членов GetHashCode(); построение - это O (N), и будет ли вычисляться хэш-код при построении объекта или когда он будет запрошен первым, общая стоимость его вычисления будет равна не более O (N).

Нет причин, чтобы какой-либо класс никогда не сталкивался с трудностями при реализации хеш-кода. Если класс использует ссылочное равенство, то по умолчанию GetHashCode является идеальным.Если он использует изменяемое определение равенства, то договор GetHashCode() может быть выполнен простым возвратом константы. Попытка помещать более чем несколько экземпляров в словарь может привести к низкой производительности, но возможно, что кто-то может использовать словарь для поиска, например. дюжина элементов в нем, и производительность была бы прекрасна со словарем такого размера.

 Смежные вопросы

  • Нет связанных вопросов^_^