标题已经说得很清楚了。当我在通过我的类进行一些反射时,MemberInfo.GetCustomAttributes() 方法是否会保留成员上属性的顺序?官方文档并没有明确说明。
如果你想知道为什么我需要这个,这里是完整的解释。它很冗长,对于现在提出的问题来说并不需要,但也许有人能想出一个不需要依靠属性枚举顺序的更好的解决方案来解决这个更大的问题。
我正在尝试为一个(ASP.NET)应用程序制作一个灵活的框架,该应用程序预计将具有相当长的生命周期。在此过程中,它将获得许多表单,这些表单必须从菜单中访问。为了让开发人员更轻松地使用,我创建了一个 MenuItemAttribute
,你可以将其应用于表单的类。这个属性在它的构造函数中有无限数量的字符串参数,允许开发人员指定表单在菜单中的位置。一个典型的用法示例可能是类似于 [MenuItem("Company", "Clients", "Orders")]
这样的代码,这意味着菜单上应该有一个名为“公司”的项,在其下面有一个名为“客户”的项,在其下面有一个名为“订单”的项,单击它就可以打开表单。如果需要,一个单独的表单可以有几个这样的属性,那么它将可以从菜单中的多个位置访问。
显然,整个菜单是通过枚举我程序集中的所有类并搜索此属性来在运行时构建的。然而,最近我收到了一个请求,要求菜单项按预定义的方式排序。具有相关功能的表单应该在菜单中相邻。请注意,这不是按字母顺序排序,而是由开发人员指定的预定义顺序。
这就带来了问题 - 如何在这些属性中指定顺序?由于一个 MenuItemAttribute
描述了整个层次结构,因此顺序规范也应包括整个(或至少一部分)层次结构的顺序号码。仅针对层次结构较低的阶段的排序编号是不够的。
我可以创建另一个属性-MenuItemOrderHintAttribute
,但是当存在多个MenuItemAttribute
的情况下,这将带来问题。因此,出现了最初的问题。
我也可以扩展MenuItemAttribute
以使用两个数组或一组对,但那会使语法变得复杂。最后的想法是使字符串具有特殊格式,但在我看来那会很混乱。
好的,我有另一个想法。让我们使用Jon Skeet建议的排序方式。这将允许为层次结构的最后一级指定顺序,而不是更高的级别。但我可以修改属性,以便它不仅适用于类,还适用于程序集本身。在这种情况下,菜单项将不具有关联的表单。在程序集级别上,这些属性可以用于指定在层次结构的较高级别之间的排序。
这是集中式和分散式菜单系统之间的权衡。有什么想法认为这是个坏主意吗?