Я бы на самом деле сказал, что для любой структуры следует всегда вручную кодировать переопределение Equals()
и GetHashCode()
вместе с реализацией IEquatable<T>
, если есть вероятность, что он может быть использован кем-то в качестве ключа, поэтомуЯ, конечно, не стал бы использовать его просто для того, чтобы этого не делать.
Помимо того, что требуется бокс, реализация по умолчанию довольно медленная, так как для изучения полей используется отражение.Есть также ошибка, по крайней мере, в некоторых версиях фреймворка (реализация вполне разумно оптимизирует как бинарное сравнение, когда это дает правильные результаты, но, к сожалению, неправильно оценивает, когда это так, и, следовательно, две структуры, содержащие эквивалент decimal
поля могут считаться неравными).
Когда требуется быстрая составная схема, которая на самом деле не имеет никакого значения для системы, кроме того, что она представляет собой составной ключ, я рекомендую использовать Tuple
.Tuple.Create()
позволяет легко их составлять, и переопределения для Equals()
и GetHashCode()
вполне разумны.
В некоторых случаях также может быть целесообразно использовать анонимные классы в качестве ключей (только в контекстеданного метода, конечно), и здесь переопределения для Equals()
и GetHashCode()
также довольно разумны.