مشاركة عبر


كتابة سمات مخصصة

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

الخطوات الأساسية لتصميم فئات السمات المخصصة بشكل صحيح هي كما يلي:

  • تطبيق AttributeUsageAttribute

  • تعريف فئة السمة

  • وحدات إنشاء التعريف

  • خصائص التعريف

يصف هذا المقطع يصف كل خطوة من هذه الخطوات و تستنتج من مثال للسمة المخصصة.

تطبيق AttributeUsageAttribute

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

[AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = true)]
<AttributeUsage(AttributeTargets.All, Inherited := False, AllowMultiple := true)>

System.AttributeUsageAttribute لديها ثلاثة أعضاء هامة لإنشاء السمات المخصصة: AttributeTargets، و Inherited، و AllowMultiple.

العضو AttributeTargets

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

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

[AttributeUsage (AttributeTargets.Class | AttributeTargets.Method)]
<AttributeUsage (AttributeTargets.Class Or AttributeTargets.Method)>

الخصائص الموروثة

تشير الخاصية Inherited إلى ما إذا كانت السمة الخاص بك يمكن توارثها بواسطة الفئات المشتقة التي يتم تطبيق السمة الخاصة بك عليها. تأخذ هذه الخاصية إما الإشارة true (بشكل الافتراضي) أو الإشارة false. على سبيل المثال، في مثال التعليمات البرمجية التالي، في MyAttribute تحتوي الخاصية افتراضياً Inherited علي القيمة true، بينما في YourAttribute تحتوي الخاصية Inherited علي القيمة false .

//This defaults to Inherited = true.
public class MyAttribute :Attribute
{
}
[AttributeUsage( Inherited = false)]
public class YourAttribute : Attribute
{
}
<AttributeUsage( AttributeTargets.All, Inherited := True)> Public Class _
MyAttribute
    Inherits Attribute
End Class

<AttributeUsage( AttributeTargets.All, Inherited := False)> Public Class _
YourAttribute
    Inherits Attribute
End Class

ثم يتم تطبيق السمتين علي الأسلوب في الفئة الأساسية MyClass.

public class MyClass
{
    [MyAttribute]
    [YourAttribute]
    public virtual void MyMethod() 
    {
        //...
    }
}
' In Microsoft Visual Basic, you apply multiple attributes
' by separating them with commas.
Public Class [MyClass]
    <MyAttribute, YourAttribute> Public Overridable Sub MyMethod()
        '...
    End Sub
End Class

وأخيراً،يتم توريث الفئة YourClass من الفئة الأساسية MyClass. الأسلوب MyMethod يُظهر MyAttribute ، لكن لا يُظهر YourAttribute.

public class YourClass: MyClass
{
      //MyMethod will have MyAttribute but not YourAttribute.
      public override void MyMethod()
      {
         //...
      }

}
Public Class YourClass
   Inherits [MyClass]
      'MyMethod will have MyAttribute but not YourAttribute.
      Public overrides Sub MyMethod()
         '...
      End Sub
End Class

الخاصية AllowMultiple

تشير الخاصية AllowMultiple إلى إمكانية وجود المثيلات المتعددة للسمة الخاصة بك علي عنصر. في حالة التعيين إلى true، فسيتم السماح بالمثيلات المتعددة; وإذا كان التعيين إلى false (الافتراضي) ، فسيتم السماح بمثيل واحد فقط.

في مثال التعليمات البرمجية التالي، تحتوي MyAttribute علي الخاصية AllowMultiple بشكل افتراضي بالقيمة false، بينما تحتوي YourAttribute علي القيمة true .

//This defaults to AllowMultiple = false.
public class MyAttribute :Attribute
{
}

[AttributeUsage(AllowMultiple = true)]
public class YourAttribute : Attribute
{
}
'This defaults to AllowMultiple = false.
<AttributeUsage(AttributeTargets.Method)> Public Class _
MyAttribute
    Inherits Attribute
End Class

<AttributeUsage(AttributeTargets.Method, AllowMultiple := True)> Public Class _
YourAttribute
    Inherits Attribute
End Class

عندما يتم تطبيق المثيلات المتعددة من هذه السمات، فستقوم MyAttribute بإنتاج خطأ في المحول البرمجي. يُظهر مثال التعليمات البرمجية التالي الاستخدام المتاح لـ YourAttribute والاستخدم غير المتاح لـ MyAttribute.

public class MyClass
{
    //This produces an error.
    //Duplicates are not allowed.
    [MyAttribute]
    [MyAttribute]
    public void MyMethod() {
        //...
    }

    //This is valid.
    [YourAttribute]
    [YourAttribute]
    public void YourMethod(){
    //...
    }
}
' In Microsoft Visual Basic you apply multiple attributes
' by separating them with commas.
Public Class [MyClass]
    'This produces an error.
    'Duplicates are not allowed.
    <MyAttribute, MyAttribute> Public Overridable Sub MyMethod()
        '...
    End Sub

    'This is valid.    
    <YourAttribute, YourAttribute> Public Sub YourMethod()
        '...
    End Sub
End Class

في حالة تعيين كل من الخاصية AllowMultiple و الخاصية Inherited إلى true، فالفئة التي تم توارثها من فئة أخرى يمكن توريثها للسمة والحصول علي مثيل آخر من نفس السمة مُطبق في نفس الفئة التابعة. إذا تم تعيين AllowMultipleإلي false، فقيم أية سمات في الفئة الأصلية سيتم الكتابة فوقها بواسطة المثيلات الجديدة من نفس السمة في الفئة التابعة.

تعريف فئة السمة

بعدما تقوم بتطبيق AttributeUsageAttribute، يمكنك البدء بتعريف مواصفات السمة الخاص بك. يشبه تعريف فئة السمة تعريف الفئة التقليدية كما هو موضّح بواسطة التعليمة البرمجية التالية.

public class MyAttribute : System.Attribute 
{
    // . . . 
}
' This attribute is only usable with methods
<AttributeUsage(AttributeTargets.Method)> Public Class MyAttribute
    Inherits System.Attribute
    ' . . . 
End Class

تعريف السمة هذا يوضح النقاط التالية:

  • يجب تعريف فئات السمة مثل الفئات العامة.

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

  • جميع فئات السمة يجب أن يورث بشكل مباشر أو غير مباشر من System.Attribute .

  • في Microsoft Visual Basic، يجب أن تكون كافة فئات السمة المخصصة لديها السمة AttributeUsageAttribute.

وحدات إنشاء التعريف

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

public MyAttribute(bool myvalue)
{
    this.myvalue = myvalue;        
}
Public Sub New(newvalue As Boolean)
    Me.myvalue = newvalue
End Sub

يمكنك زيادة تحميل المُنشئ ليحتوي علي تركيبات مختلفة من القيم. إذا قمت أيضاً بتحديد property إلي فئة السمة المخصصة، يمكنك استخدام تركيبة من المعلمات المسماة و الموضعية عند تهيئة السمة. بشكل عام، قم بتعريف كافة المعلمات المطلوبة كمعلمة موضعية وجميع المعلمات الاختيارية كمعلمات مسماة. في هذه الحالة، لا يمكن تهيئة السمة دون المعلمة المطلوبة. وتكون كافة المكونات الأخرى اختيارية. لاحظ أنه في Visual Basic، وحدات الإنشاء الخاصة بفئة السمة لا يجب أن تستخدام وسيطة ParamArray.

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

//One required (positional) and one optional (named) parameter are applied.
[MyAttribute(false, OptionalParameter = "optional data")]
//One required (positional) parameter is applied.
[MyAttribute(false)]
'One required (positional) and one optional (named) parameter are applied.
<MyAttribute(False, OptionalParameter := "optional data")>
' ...
'One required (positional) parameter is applied.
<MyAttribute(False)>

تعريف الخصائص

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

public bool MyProperty
{
    get {return this.myvalue;}
    set {this.myvalue = value;}
}
Public Property MyProperty As Boolean
    Get
        Return Me.myvalue
    End Get
    Set
        Me.myvalue = value
    End Set
End Property

مثال علي السمة المخصصة

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

[AttributeUsage(AttributeTargets.All)]
public class DeveloperAttribute : System.Attribute 
{
        
    //Private fields.
    private string name;
    private string level;
    private bool reviewed;

    //This constructor defines two required parameters: name and level.

    public  DeveloperAttribute(string name,string level)
    {
        this.name = name;
        this.level = level; 
        this.reviewed = false;
    }

    //Define Name property.
    //This is a read-only attribute.
        
    public virtual string Name
    {
        get {return name;}        
    }

    //Define Level property.
    //This is a read-only attribute.
        
    public virtual string Level
    {
        get {return level;}
    }

    //Define Reviewed property. 
    //This is a read/write attribute. 

    public virtual bool Reviewed
    {
        get {return reviewed;}
    set {reviewed = value;}
    }
}
<AttributeUsage(AttributeTargets.All)> Public Class DeveloperAttribute
    Inherits System.Attribute
    
    'Private fields.
    Private m_name As String
    Private m_level As String
    Private m_reviewed As Boolean    
    
    'This constructor defines two required parameters: name and level.
    Public Sub New(name As String, level As String)
        Me.m_name = name
        Me.m_level = level
        Me.m_reviewed = False
    End Sub
    
    'Define Name property.
    'This is a read-only attribute.    
    Public Overridable ReadOnly Property Name() As String
        Get
            Return m_name
        End Get
    End Property 
    
    'Define Level property.
    'This is a read-only attribute.    
    Public Overridable ReadOnly Property Level() As String
        Get
            Return m_level
        End Get
    End Property
    
    'Define Reviewed property. 
    'This is a read/write attribute.    
    Public Overridable Property Reviewed() As Boolean
        Get
            Return m_reviewed
        End Get
        Set
            m_reviewed = value
        End Set
    End Property
End Class

يمكنك تطبيق هذه السمة باستخدام الاسم الكامل DeveloperAttribute، أو باستخدام الاسم المختصر Developer، بإحدى الطرق التالية.

[Developer("Joan Smith", "1")]
[Developer("Joan Smith", "1", Reviewed = true)]
<Developer("Joan Smith", "1")>
<Developer("Joan Smith", "1", Reviewed := True)>

يُظهر المثال الأول السمة المُطبقة مع المعلمات المسماة المطلوبة فقط، بينما يُظهر المثال الثاني أن السمة المُطبقة علي كلا من المعلمات المطلوبة والاختيارية.

راجع أيضًا:

المرجع

System.Attribute

AttributeUsageAttribute

المبادئ

توسيع بيانات التعريف باستخدام السمات