タイトルはほとんどそれをすべて言います。クラスを介していくつかのリフレクションを行っている場合、MemberInfo.GetCustomAttributes() メソッドはメンバーの属性の順序を保持しますか? 公式ドキュメントには、いずれにしても何も書かれていません。
なぜこれが必要なのか疑問に思っている場合は、ここに完全な説明があります。それは長く、現在提起されている質問には必要ありませんが、属性の列挙順序に依存しない、より大きな問題に対する代替の解決策を誰かが考え出すことができるかもしれません。
かなり長い寿命が期待される (ASP.NET) アプリケーション用の柔軟なフレームワークを作成しようとしています。コースの過程で、メニューからアクセスできる必要がある多くのフォームが得られます。開発者の負担を軽減MenuItemAttribute
するために、フォームのクラスに適用できる を作成しました。この属性のコンストラクターには無制限の量の文字列パラメーターがあり、開発者はフォームがメニュー内のどこに存在するかを正確に指定できます。典型的な使用例は次のようになります[MenuItem("Company", "Clients", "Orders")]
これは、メニューに「会社」という項目があり、その下に「クライアント」という項目があり、その下に「注文」という項目があり、フォームが開くことを意味します。必要に応じて、単一のフォームにこれらの属性をいくつか含めることができます。これにより、メニューのいくつかの場所からアクセスできるようになります。
明らかに、アセンブリ内のすべてのクラスを列挙し、この属性を検索することにより、メニュー全体が実行時に構築されます。しかし最近、メニュー項目を事前定義された方法でソートする必要があるというリクエストを受け取りました。関連する機能を持つフォームは、メニュー内で隣り合わせにする必要があります。これはアルファベット順ではなく、開発者が指定した定義済みの順序であることに注意してください。
これにより問題が発生します。これらの属性で順序を指定するにはどうすればよいですか? 階層全体を記述するためMenuItemAttribute
、注文仕様には階層全体 (または少なくとも一部) の注文番号も含める必要があります。階層の下位レベルの注文番号だけでは十分ではありません。
別の属性 - を作成することもできますMenuItemOrderHintAttribute
が、複数ある場合に問題が発生しMenuItemAttribute
ます。したがって、元の質問。
MenuItemAttribute
2 つの配列またはペアの配列のいずれかを取るように を拡張することもできますが、それでは構文が非常に複雑になります。最後のアイデアは、文字列に特別な形式を持たせることができるということですが、それはかなり面倒です。
わかりました、別のアイデアがあります。Jon Skeet が提案した順序を使用しましょう。これにより、階層の上位レベルではなく、最終レベルの順序を指定できます。しかし、クラスだけでなく、アセンブリ自体にも適用されるように、属性を変更できます。この場合、メニュー項目にはフォームが関連付けられていません。アセンブリ レベルでは、これらの属性を使用して、階層の上位レベル間の順序を指定できます。
これは、集中型メニュー システムと分散型メニュー システムの間のトレードオフです。なぜこれが悪い考えになるのでしょうか?