تقييد سمة مخصصة بحيث يمكن تطبيقه فقط على أنواع محددة في C# ؟

StackOverflow https://stackoverflow.com/questions/1021190

  •  06-07-2019
  •  | 
  •  

سؤال

لدي سمة مخصصة والتي يتم تطبيقها على خصائص الطبقة و الطبقة نفسها.الآن جميع الفئات التي يجب أن تطبق بلدي سمة مخصصة مستمدة من قاعدة واحدة الفئة.

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

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

المحلول

الرتق, أنا أكره ذلك عندما أثبت نفسي على خطأ...أنه يعمل إذا كنت تحديد السمة كما المحمية متداخلة نوع من قاعدة الدرجة:

abstract class MyBase {
    [AttributeUsage(AttributeTargets.Property)]
    protected sealed class SpecialAttribute : Attribute {}
}

class ShouldBeValid : MyBase {
    [Special]
    public int Foo { get; set; }
}
class ShouldBeInvalid {
    [Special] // type or namespace not found
    [MyBase.Special] // inaccessible due to protection level
    public int Bar{ get; set; }
}

(الجواب الأصلية)

لا يمكنك أن تفعل هذا - على الأقل ليس في وقت الترجمة.

سمات يمكن أن يقتصر (على حصول exmaple) إلى "الطبقة", "البنية" و "الأسلوب" ، "الميدان" ، وما إلى ذلك - ولكن لا شيء أكثر دقة.

بالطبع, منذ سمات تفعل شيئا من قبل أنفسهم (تجاهل PostSharp) ، وسوف تكون خاملة على أنواع أخرى (وخامل على أنواع بك إلا إذا قمت بإضافة بعض التعليمات البرمجية إلى نظرة على السمات في وقت التشغيل).

يمكنك كتابة التقدم القاعدة, لكن هذا يبدو مبالغة.

أتساءل ما إذا كانت سمة هو أفضل خيار:

الآن جميع الفئات التي يجب أن تطبق بلدي سمة مخصصة مستمدة من قاعدة واحدة الفئة.

إذا كانت يجب أن تطبيق سمة مخصصة, ربما abstract (أو ربما فقط virtual) الملكية / الطريقة سيكون خيار أفضل ؟

abstract class MyBase {
    protected abstract string GetSomeMagicValue {get;}
}
class MyActualType : MyBase {
    protected override string GetSomeMagicValue {get {return "Foo";}}
}

نصائح أخرى

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

وهكذا

class MyAttribute
{
     // put whatever custom data you want in here
}

interface IAttributeService<T> where T : MyBaseClass
{
     MyAttribute Value{get;}
}

وثم الفئة الأساسية الخاصة بك أن تفعل هذا

class MyBaseClass : IAttributeService<MyBaseClass>
{
     private MyAttribute m_attrib;

     IAttributeService<MyClass>.Value
     {
         get {return m_attrib;}
     }
}

وبهذه الطريقة سوف مترجم فرض القيد في وقت الترجمة بحيث فصول فقط
المستمدة من MyBaseClass يمكن تنفيذ واجهة.
أنا جعلت من توسع إلى حد ما عن طريق تحديد فئة MyAttribute ولكن هل يمكن بطبيعة الحال مجرد إرجاع سلسلة أو منطقي إذا كنت بحاجة إلى شيء أكثر بساطة

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

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