В продукте используется множество разнообразных Id представленных в виде Guid или String.
Не редко разработчики допускают ошибки, подменяя одно понятие другим в процессе взаимодействия между компонентами.
Появилось коварное желание обернуть наиболее проблемные из них в управляемые обертки.
И встал вопрос — во что? Классы или структуры?
По началу, выбор был очевиден — структуры, благодаря минимальному оверхеду.
Но есть недостаток — структуры не наследуются. А это означает, что:
1) На каждый тип будет создано по меньшей мере 5 методов — операторы сравнения, а также Equals, GetHashCode и ToString, для комфортной работы, ещё 4, для реализации IFormattable, IComparable, IComparable<Guid>, IEquatable<Guid>
2) В одном случае идентификаторы могут наследоваться. Условно говоря, путь к файлу является также путём на файловой системе. Значит в каждом наследнике придётся реализовать implicit-операторы для конвертации в родителя.
После этого выбор в пользу структур перестал быть столь однозначным.
Предположим, что таких типизированных идентификаторов будет не больше 300, но не меньше 100, в рабочем процессе участвует не меньше 100, но не больше 40 000 000 экземпляров сущностей, у каждой из которых есть такой идентификатор. Какое решение подойдёт больше и почему?