【发布时间】:2009-01-26 14:47:53
【问题描述】:
标题几乎说明了一切。当我通过我的类进行一些反思时,MemberInfo.GetCustomAttributes() 方法是否会保留成员的属性顺序?官方文档并没有说什么。
如果您想知道我为什么需要这个,这里是完整的解释。现在提出的问题很长而且不需要,但也许有人可以为更大的问题想出一个替代解决方案,它不涉及依赖属性枚举顺序。
我正在尝试为预期具有相当长生命周期的 (ASP.NET) 应用程序创建一个灵活的框架。在整个过程中,它将获得许多必须从菜单中访问的表格。为了让开发人员的生活更轻松,我创建了一个MenuItemAttribute,您可以将其应用于表单的类。此属性在其构造函数中具有无限数量的字符串参数,允许开发人员指定表单在菜单中的确切位置。一个典型的使用示例类似于[MenuItem("Company", "Clients", "Orders")],这意味着菜单应该有一个项目“公司”,在该项目下将有一个项目“客户”,在该项目下将有一个项目“订单” - 然后将打开表格。如果需要,单个表单可以具有多个这些属性 - 然后可以从菜单中的多个位置访问它。
显然,整个菜单是在运行时通过枚举我的程序集中的所有类并搜索该属性来构建的。但是最近我收到了一个请求,即菜单项应该以预定义的方式进行排序。具有相关功能的表单应在菜单中彼此相邻。请注意,这不是按字母排序,而是开发人员指定的预定义顺序。
这就带来了问题——如何在这些属性中指定顺序?由于一个MenuItemAttribute 描述了整个层次结构,因此订单规范还应包括整个(或至少一部分)层次结构的订单号。仅较低层次的订单号是不够的。
我可以创建另一个属性 - MenuItemOrderHintAttribute,但是当有多个 MenuItemAttribute 时,这会带来问题。因此是最初的问题。
我还可以扩展MenuItemAttribute 以获取两个数组或一对数组,但这会使语法复杂化很多。最后一个想法是我可以使字符串具有特殊格式,但恕我直言,这将是相当混乱的。
好的,我有另一个想法。让我们使用 Jon Skeet 建议的顺序。这将允许指定层次结构的最后一级的顺序,而不是更高的。但我可以修改该属性,使其不仅适用于类,还适用于程序集本身。在这种情况下,菜单项将没有关联的表单。在装配级别,这些属性可用于指定层次结构更高级别之间的顺序。
这是集中式和分散式菜单系统之间的权衡。有什么想法为什么这是个坏主意?
【问题讨论】:
-
权衡确实避免了必须处理更高级别的冲突值(MenuA 说 Bar 出现在 2,MenuB 说 Bar 出现在 4,MenuC 说 Baz 出现在 3。Bar 和 Baz 出现的顺序是什么?在?)
-
这就是为什么我将它们称为“提示”。我意识到使用这个模型我无法避免这样的冲突。事实上,由于应用程序是可插件的,我不可能有一个集中的菜单定义。
标签: .net reflection attributes enumeration