GetCustomAttributes() 是否保留 .NET 中的屬性順序?
標題基本概括了所有內容。當我通過我的類進行一些反思時,MemberInfo.GetCustomAttributes() 方法是否會保留成員的屬性順序?官方文件並沒有以任何方式說明任何事情。
如果你想知道我為什麼需要這個,這裡是完整的解釋。現在提出的問題很長而且不需要,但也許有人可以為更大的問題想出一個替代解決方案,它不涉及依賴屬性列舉順序。
我正在嘗試為(ASP.NET)應用程序創建一個靈活的框架,該應用程序預計具有相當長的生命週期。在整個過程中,它將獲得許多必須從菜單中訪問的表格。為了讓開發人員的生活更輕鬆,我製作了一個
MenuItemAttribute您可以將其應用於表單的類。此屬性在其建構子中具有無限數量的字元串參數,允許開發人員指定表單在菜單中的確切位置。一個典型的使用範例是這樣的[MenuItem("Company", "Clients", "Orders")]這意味著菜單應該有一個項目“公司”,在該項目下將有一個項目“客戶”,在該項目下將有一個項目“訂單” - 然後將打開表單。如果需要,單個表單可以具有多個這些屬性 - 然後可以從菜單中的多個位置訪問它。顯然,整個菜單是在執行時通過列舉我的程序集中的所有類並蒐索該屬性來建構的。但是最近我收到了一個請求,即菜單項應該以預定義的方式進行排序。具有相關功能的表單應在菜單中彼此相鄰。請注意,這不是按字母排序,而是開發人員指定的預定義順序。
這就帶來了問題——如何在這些屬性中指定順序?由於
MenuItemAttribute描述了整個層次結構,因此訂單規範還應包括整個(或至少一部分)層次結構的訂單號。僅針對較低層次結構的訂單號是不夠的。我可以製作另一個屬性 -
MenuItemOrderHintAttribute,但是當有多個屬性時,這會帶來問題MenuItemAttribute。因此,原來的問題。我還可以將 擴展
MenuItemAttribute為採用兩個數組或一對數組,但這會使語法複雜化很多。最後一個想法是我可以使字元串具有特殊格式,但恕我直言,那將是相當混亂的。好的,我有另一個想法。讓我們使用 Jon Skeet 建議的順序。這將允許指定層次結構的最後一級的順序,而不是更高的。但我可以修改該屬性,使其不僅適用於類,還適用於程序集本身。在這種情況下,菜單項將沒有關聯的表單。在裝配級別,這些屬性可用於指定層次結構更高級別之間的排序。
這是集中式和分散式菜單系統之間的權衡。任何想法為什麼這是一個壞主意?
我會在 MenuItemAttribute 建構子中添加一個額外的(可選)值,即“訂單”或“優先級”:
[MenuItem(0, "Company", "Clients", "Orders")] [MenuItem(1, "Foo", "Bar", "Baz")]我並不是說它會很漂亮,但它可以有效地讓您指定排序。
文件中元素的詞法順序絕對不能保證在生成的 CIL 程序集中以任何方式保持不變,也不能在反射返回的結果中得到尊重。在同一個應用程序域內的重複呼叫中,甚至不能保證這種排序是相同的!
請注意,MS 過去在反射的其他部分中破壞了這種順序(注意到他們這樣做實際上給他們的一些程式碼造成了一些問題),因此即使它目前恰好工作,也沒有什麼能阻止這種破壞將來或在不同的平台上。
考慮更改您的屬性模型以允許直接表達語義資訊,而不是依賴於排序。