Does GetCustomAttributes() preserve the attribute order in .NET?

前端 未结 4 1407
-上瘾入骨i
-上瘾入骨i 2020-12-11 01:17

The title pretty much says it all. When I\'m doing some reflection through my classes, will the MemberInfo.GetCustomAttributes() method preserve the order of attributes on a

相关标签:
4条回答
  • 2020-12-11 01:35

    Unfortunately no, you cannot guarantee that the order will be the same as the order in which you specified them.

    Edit: a workaround

    Disclaimer: I apologize ahead of time if I am misunderstanding your ultimate problem.

    It sounds as if you need to be able to pass n number of strings to MenuItemAttribute and have MenuItemAttribute maintain the order of these strings as entered by the developer in the attributes constructor.

    Here is a possible solution:

    Have MenuItemAttribute use a LinkedList<String> to maintain its state. Then you can iterate the params String[] in your constructor and add them to the LinkedList<String> which would maintain the order.

    0 讨论(0)
  • 2020-12-11 01:47

    The lexical ordering of elements in a file is absolutely not guaranteed to be persisted in anyway in the resulting CIL assemblies nor to be respected in the results returned from Reflection. This ordering is not even guaranteed to be the same over repeated calls within the same app domain!

    Note that MS have broken this ordering in other parts of reflection in the past (Noting as they did it that this actually caused some issues for some of their code), thus even if it happens to work at the moment there is nothing stopping this breaking in future or on different platforms.

    Consider changing your attribute model to allow expressing the semantic information directly rather than relying on ordering.

    0 讨论(0)
  • 2020-12-11 01:47

    It seems to me that your problem really stems from the fact that the forms are specifying where they appear in your menu, which means you're trying to build a menu by combining all the forms in an assembly. It might be easier if you specify the structure of the menu separately from any forms, and resolve the forms from various propeties/attributes defined on the class corresponding to a menu item.

    e.g.

    public class MenuItem
    {
        string Text { get; }
        Type FormType { get; }
        ICollection<MenuItem> SubItems { get; }
    }
    

    Then when a menu-item is selected, resolve the form somehow and display it. This approach has the disadvantage that any new forms need require a change to the code specifying the menu structure along with the form itself, but that will be quite minor...

    0 讨论(0)
  • 2020-12-11 01:56

    I'd put a single extra (optional) value in the MenuItemAttribute constructor, which is "order" or "priority":

    [MenuItem(0, "Company", "Clients", "Orders")]
    [MenuItem(1, "Foo", "Bar", "Baz")]
    

    I'm not saying it would be pretty, but it would effectively allow you to specify the ordering.

    0 讨论(0)
提交回复
热议问题