كتابة سمات مخصصة
لكي تصمم السمات المخصصة الخاصة بك، فلن تحتاج إلى أن تتعلم العديد من المفاهيم الجديدة. إذا كنت على علم بالبرمجة الموجهة نحو الكائانت و تعرف كيفية تصميم الفئات، إذن فأنت بالفعل لديك معظم المعلومات المطلوبة. السمات المخصصة هي فئات تقليدية بشكل أساسي وهي مشتقة بشكل مباشر أو غير مباشر من 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)>
يُظهر المثال الأول السمة المُطبقة مع المعلمات المسماة المطلوبة فقط، بينما يُظهر المثال الثاني أن السمة المُطبقة علي كلا من المعلمات المطلوبة والاختيارية.