سؤال

العنوان إلى حد كبير يقول كل شيء.عندما أقوم ببعض التفكير خلال الفصول الدراسية الخاصة بي، هل ستحافظ طريقة MemberInfo.GetCustomAttributes() على ترتيب السمات على العضو أم لا؟الوثائق الرسمية لا تقول أي شيء بطريقة أو بأخرى.


في حال كنت تتساءل لماذا أحتاج إلى هذا، فإليك الشرح الكامل.إنها طويلة وليست ضرورية للسؤال كما هو مطروح الآن، ولكن ربما يستطيع شخص ما التوصل إلى حل بديل للمشكلة الأكبر التي لا تنطوي على الاعتماد على ترتيب تعداد السمات.

أحاول إنشاء إطار عمل مرن لتطبيق (ASP.NET) من المتوقع أن يكون له عمر طويل جدًا.على مدار الدورة، سوف يكتسب العديد من النماذج التي يجب الوصول إليها من القائمة.ولجعل الحياة أسهل بالنسبة للمطورين، قمت بإنشاء ملف MenuItemAttribute والتي يمكنك تطبيقها على فئة النموذج.تحتوي هذه السمة على عدد غير محدود من معلمات السلسلة في منشئها مما يسمح للمطور بتحديد المكان الذي سيتواجد فيه النموذج بالضبط في القائمة.مثال الاستخدام النموذجي سيكون شيئًا مثل [MenuItem("Company", "Clients", "Orders")] مما يعني بعد ذلك أن القائمة يجب أن تحتوي على عنصر "الشركة" والذي سيكون ضمنه عنصر "العملاء" والذي سيكون ضمنه عنصر "الطلبات" - والذي سيفتح النموذج بعد ذلك.يمكن أن يحتوي النموذج الواحد على العديد من هذه السمات إذا لزم الأمر - وسيكون من الممكن بعد ذلك الوصول إليه من عدة أماكن في القائمة.

من الواضح أن القائمة بأكملها تم إنشاؤها في وقت التشغيل من خلال تعداد جميع الفئات في تجميعاتي والبحث عن هذه السمة.ولكنني تلقيت مؤخرًا طلبًا بضرورة فرز عناصر القائمة بطريقة محددة مسبقًا.يجب أن تكون النماذج ذات الوظائف المرتبطة بجوار بعضها البعض في القائمة.لاحظ أن هذا ليس فرزًا أبجديًا، ولكنه ترتيب محدد مسبقًا يحدده المطورون.

وهذا يجلب المشكلة - كيف أحدد الترتيب في هذه السمات؟منذ واحد MenuItemAttribute يصف تسلسلًا هرميًا كاملاً، ويجب أن تتضمن مواصفات الطلب أيضًا أرقام الطلب لكامل (أو على الأقل جزء) من التسلسل الهرمي.رقم الطلب للمستوى الأدنى فقط من التسلسل الهرمي ليس كافيًا.

يمكنني أن أصنع سمة أخرى - MenuItemOrderHintAttribute, ، ولكن هذا من شأنه أن يسبب مشاكل في الحالات التي يوجد فيها أكثر من حالة واحدة MenuItemAttribute.ومن هنا السؤال الأصلي.

يمكنني أيضًا تمديد MenuItemAttribute لأخذ صفيفين أو مجموعة من الأزواج، ولكن ذلك سيؤدي إلى تعقيد بناء الجملة كثيرًا.الفكرة الأخيرة هي أنه يمكنني جعل السلاسل ذات تنسيق خاص، لكن ذلك سيكون فوضويًا إلى حد ما.


حسنًا، لدي فكرة أخرى.دعونا نستخدم الترتيب الذي اقترحه جون سكيت.سيسمح هذا بتحديد ترتيب المستوى الأخير من التسلسل الهرمي، وليس المستويات الأعلى.ولكن يمكنني تعديل السمة بحيث لا تنطبق فقط على الفئات، ولكن أيضًا على التجميع نفسه.في هذه الحالة، لن يكون لعنصر القائمة نموذج مرتبط.على مستوى التجميع، يمكن بعد ذلك استخدام هذه السمات لتحديد الترتيب بين المستويات الأعلى من التسلسل الهرمي.

وهذه إذن عبارة عن مقايضة بين نظام القائمة المركزي واللامركزي.أي أفكار لماذا هذه فكرة سيئة؟

هل كانت مفيدة؟

المحلول

وكنت وضعت على (اختياري) قيمة واحدة إضافية في منشئ MenuItemAttribute، وهو "النظام" أو "الأولوية":

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

وأنا لا أقول أنه سيكون جدا، لكنه سيسمح بشكل فعال لك لتحديد الطلب.

نصائح أخرى

الترتيب المعجمي للعناصر في الملف هو قطعاً ليس من المضمون أن يستمر بأي حال من الأحوال في تجميعات CIL الناتجة ولا أن يتم احترامه في النتائج التي يتم إرجاعها من التأمل.لا يمكن ضمان أن يكون هذا الترتيب هو نفسه عبر المكالمات المتكررة داخل نفس نطاق التطبيق!

لاحظ أن MS قد كسر هذا الترتيب في أجزاء أخرى من الانعكاس في الماضي (لاحظ أنهم فعلوا ذلك تسبب في الواقع في بعض المشكلات لبعض أكوادهم البرمجية)، وبالتالي، حتى لو حدث ذلك للعمل في الوقت الحالي، فلا يوجد شيء يوقف هذا الكسر في المستقبل أو على منصات مختلفة.

فكر في تغيير نموذج السمة الخاص بك للسماح بالتعبير عن المعلومات الدلالية مباشرة بدلاً من الاعتماد على الترتيب.

للأسف لا، لا يمكنك ضمان أن النظام سوف يكون نفس الترتيب الذي حددته لهم.

تحرير: حلا

تنويه: أعتذر قبل الموعد المحدد إذا أنا سوء الفهم مشكلة النهائي الخاص بك

.

ويبدو كما لو كنت بحاجة إلى أن تكون قادرة على تمرير عدد n من السلاسل إلى MenuItemAttribute ويكون MenuItemAttribute حفاظ على النظام من هذه السلاسل كما دخلت من قبل المطور في منشئ الصفات.

وهنا هو الحل الممكن:

هل لديك MenuItemAttribute استخدام LinkedList<String> للحفاظ على حالته. ثم يمكنك تكرار هذا params String[] في منشئ وإضافتها إلى LinkedList<String> التي من شأنها الحفاظ على النظام.

ويبدو لي أن مشكلتك تنبع حقا من حقيقة أن أشكال يتم تعيين حيث تظهر في القائمة الخاصة بك، مما يعني أنك تحاول بناء قائمة من خلال الجمع بين جميع أشكال في التجمع. قد يكون من الأسهل إذا قمت بتحديد هيكل القائمة بشكل منفصل عن أي شكل من أشكال، وحل أشكال مختلفة من propeties / سمات محددة على الطبقة المقابلة لعنصر القائمة.

ومنها مثلا.

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

وبعد ذلك عند تحديد البند القائمة، حل شكل بطريقة أو بأخرى وعرضه. هذا النهج لديه العيب أن تحتاج أي أشكال جديدة تتطلب تغيير رمز تحديد بنية القائمة جنبا إلى جنب مع النموذج نفسه، ولكن ذلك لن يكون بسيط جدا ...

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top