Название довольно много говорит обо всем. Когда я буду размышлять над своими классами, метод MemberInfo.GetCustomAttributes() сохранит порядок атрибутов для члена или нет? Официальная документация ничего не говорит так или иначе.
Если вам интересно, зачем мне это нужно, вот полное объяснение. Он длительный и не нужен для вопроса, поскольку он теперь задан, но, возможно, кто-то может придумать альтернативное решение большей проблемы, которая не связана с порядком перечисления атрибутов.
Я пытаюсь создать гибкую структуру для приложения (ASP.NET), которое, как ожидается, будет иметь довольно долгий срок службы. По ходу он получит множество форм, которые должны быть доступны из меню. Чтобы облегчить жизнь разработчикам, я сделал MenuItemAttribute
, который вы можете применить к классу формы. Этот атрибут имеет неограниченное количество строковых параметров в своем конструкторе, что позволяет разработчику указать, где именно будет находиться форма в меню. Типичным примером использования будет что-то вроде [MenuItem("Company", "Clients", "Orders")]
, которое тогда означало бы, что в меню должен быть пункт "Компания", в соответствии с которым будет элемент "Клиенты", в соответствии с которым будет элемент "Заказы", который затем откроется форма. При необходимости одна форма может иметь несколько из этих атрибутов - она будет доступна из нескольких мест в меню.
Очевидно, что все меню построено во время выполнения, перечисляя все классы в моих сборках и ища этот атрибут. Однако недавно я получил запрос, что элементы меню должны быть отсортированы заранее. Формы, имеющие соответствующую функциональность, должны быть рядом друг с другом в меню. Обратите внимание, что это НЕ сортировка по алфавиту, а предопределенный порядок, указанный разработчиками.
В этом случае возникает проблема - как указать порядок в этих атрибутах? Поскольку один MenuItemAttribute
описывает целую иерархию, спецификация заказа также должна содержать порядковые номера для целого (или, по крайней мере, части) иерархии. Номер заказа только для нижнего уровня иерархии недостаточен.
Я мог бы сделать еще один атрибут - MenuItemOrderHintAttribute
, но это может привести к проблемам с случаями, когда имеется более одного MenuItemAttribute
. Отсюда исходный вопрос.
Я мог бы также расширить MenuItemAttribute
, чтобы взять либо два массива, либо массив пар, но это усложнит синтаксис. Последняя идея заключается в том, что я могу заставить строки иметь специальный формат, но это было бы довольно беспорядочным IMHO.
Хорошо, у меня есть другая идея. Позвольте использовать заказ, предложенный Джоном Скитом. Это позволит указать порядок для последнего уровня иерархии, а не более высокие. Но я могу изменить атрибут так, чтобы он применялся не только к классам, но и к самой сборке. В этом случае элемент меню не имеет связанной формы. На уровне сборки эти атрибуты затем могут использоваться для указания порядка между более высокими уровнями иерархии.
Это тогда компромисс между централизованной и децентрализованной системой меню. Любые мысли, почему это была бы плохая идея?