مشاركة عبر


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

استرداد السمة المخصصة هي عملية بسيطة. أولاً، قم بتعريف مثيل للسمة التي ترغب استردادها. ثم استخدم أسلوب Attribute.GetCustomAttribute لتهيئة السمة الجديدة إلى قيمة السمة التي ترغب استردادها. بمجرد أن يتم تهيئة السمة الجديدة , ببساطة استخدام الخصائص الخاصة بها للحصول على القيم.

ملاحظة هامةهام

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

يصف هذا القسم الطرق التالية لاسترداد سمات:

  • استرداد مثيل واحد من سمة

  • استرداد مثيلات متعددة من سمة مُطبّقة على نفس النطاق

  • استرداد مثيلات متعددة من سمة المُطبّقة على نطاقات مختلفة

استرداد مثيل واحد من سمة

في المثال التالي DeveloperAttribute (الموضح في القسم السابق) يتم تطبيق الفئة MainApp على مستوي الفئة. يستخدم الأسلوب GetAttribute GetCustomAttribute لاسترداد القيم المخزنة على مستوي الفئة في DeveloperAttribute قبل عرضهم إلي وحدة التحكم.

using System;

[Developer("Joan Smith", "42", Reviewed = true)]
class MainApp
{
    public static void Main() 
    {
        //Call function to get and display the attribute.
        GetAttribute(typeof(MainApp));
    }
    
    public static void GetAttribute(Type t) 
    {
        
        
        //Get instance of the attribute.    
            DeveloperAttribute MyAttribute = (DeveloperAttribute) Attribute.GetCustomAttribute(t, typeof (DeveloperAttribute));
            
            if(null == MyAttribute)
            {
                Console.WriteLine("The attribute was not found.");
            }
            else
            {
                //Get the Name value.    
                Console.WriteLine("The Name Attribute is: {0}." , MyAttribute.Name);
                //Get the Level value.    
                Console.WriteLine("The Level Attribute is: {0}." , MyAttribute.Level);
                //Get the Reviewed value.
                Console.WriteLine("The Reviewed Attribute is: {0}." , MyAttribute.Reviewed);
            }
    }
}
Imports System

<Developer("Joan Smith", "42", Reviewed := True)> Class MainApp
    
    Public Shared Sub Main()
        'Call function to get and display the attribute.
        GetAttribute(GetType(MainApp))
    End Sub
    
    Public Shared Sub GetAttribute(t As Type)        
        
        'Get instance of the attribute.
        Dim MyAttribute As DeveloperAttribute = _
        CType(Attribute.GetCustomAttribute(t, GetType(DeveloperAttribute)), DeveloperAttribute)
        
        If MyAttribute Is Nothing Then
            Console.WriteLine("The attribute was not found.")
        Else
            'Get the Name value.
            Console.WriteLine("The Name Attribute is: {0}.", MyAttribute.Name)
            'Get the Level value.
            Console.WriteLine("The Level Attribute is: {0}.", MyAttribute.Level)
            'Get the Reviewed value.
            Console.WriteLine("The Reviewed Attribute is: {0}.", MyAttribute.Reviewed)
        End If
    End Sub
End Class

هذا البرنامج يعرض النص التالي عند تنفيذ.

The Name Attribute is: Joan Smith.
The Level Attribute is: 42.
The Reviewed Attribute is: True.

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

The attribute was not found. 

يفترض هذا المثال أن تعريف السمة في مساحة الاسم الحالية. تذكر أن استيراد مساحة الاسم الموجود في تعريف السمة يتأكد من عدم وجوده في مساحة الاسم الحالية.

استرداد مثيلات متعددة من سمة مُطبّقة على نفس النطاق

في المثال السابق , الفئة المراد فحصها و السمة المعينة المراد البحث عنها يتم تمريرها إلى GetCustomAttribute. تعمل تلك التعليمات البرمجية بشكل جيد إذا كان مثيل واحد فقط للسمة يتم تطبيقه على مستوى الفئة. ومع ذلك، إذا تم تطبيق مثيلات سمة متعددة على نفس مستوي الفئة ، فلن يقوم أسلوب GetCustomAttribute باسترداد كافة المعلومات. في الحالات حيث المثيلات المتعددة من نفس السمة يتم تطبيقها في نفس النطاق يمكنك استخدام Attribute.GetCustomAttributes لوضع كافة المثيلات في مصفوفة. على سبيل المثال، إذا كان هناك مثيلين من DeveloperAttribute يتم تطبيقهما على مستوي الفئة من نفس الفئة GetAttribute يمكن تعديل أسلوب عرض المعلومات في كلا السمتين. تذكر أنه لتطبيق سمات متعددة على نفس المستوى ,يجب تعريف السمة بتعيين الخاصية AllowMultiple صحيحاً في AttributeUsageAttribute.

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

public static void GetAttribute(Type t)
{
    DeveloperAttribute[] MyAttribute =
    (DeveloperAttribute[]) Attribute.GetCustomAttributes(t, typeof (DeveloperAttribute));
    
    if(null == MyAttribute)
    {
        Console.WriteLine("The attribute was not found.");
    }
    else
    {
        for(int i = 0 ; i < MyAttribute.Length ; i++)
        {
            //Get the Name value.    
            Console.WriteLine("The Name Attribute is: {0}." , MyAttribute[i].Name);
            //Get the Level value.  
            Console.WriteLine("The Level Attribute is: {0}." , MyAttribute[i].Level);
            //Get the Reviewed value.
            Console.WriteLine("The Reviewed Attribute is: {0}.", MyAttribute[i].Reviewed);
        }
    }
}
Public Shared Sub GetAttribute(t As Type)
    Dim MyAttribute As DeveloperAttribute() = _
    CType(Attribute.GetCustomAttributes(t, GetType(DeveloperAttribute)), DeveloperAttribute())
       
    If MyAttribute Is Nothing Then
        Console.WriteLine("The attribute was not found.")
    Else
        Dim i As Integer
        For i = 0 To MyAttribute.Length - 1
            'Get the Name value. 
            Console.WriteLine("The Name Attribute is: {0}.", MyAttribute(i).Name)
            'Get the Level value.   
            Console.WriteLine("The Level Attribute is: {0}.", MyAttribute(i).Level)
            'Get the Reviewed value.
            Console.WriteLine("The Reviewed Attribute is: {0}.", MyAttribute(i).Reviewed)
        Next i
    End If
End Sub

إذا لم يتم العثور على سمات ، ستنبه التعليمة البرمجية المستخدم. وإلا، المعلومات المضمنة في كلا المثيلتين DeveloperAttribute تُعرض.

استرداد مثيلات متعددة من سمة المُطبّقة على نطاقات مختلفة

أساليب GetCustomAttributes و GetCustomAttribute لا تقوم بالبحث في الفئة بأكملها ثم تقوم بإرجاع كافة مثيلات السمة في تلك الفئة. بدلاً من ذلك، تقوم بالبحث مرة واحدة فقط في أسلوب محدد أو عضو في كل مرة. إذا كان لديك فئة بنفس السمة المُطبقة على كل عضو , وتريد استرداد القيم الموجودة في كافة السمات المُطبقة علي تلك الأعضاء ، يجب إمداد كل أسلوب أو عضو بشكل فردي ب GetCustomAttributes و GetCustomAttribute .

يأخذ مثال التعليمات البرمجية التالي فئة كمعلمة و يبحث عن DeveloperAttribute (المعرفة سابقا) على مستوي الفئة وعلى كل أسلوب فردي في تلك الفئة.

public static void GetAttribute(Type t) 
{
            
    DeveloperAttribute att;

    //Get the class-level attributes.
    
    //Put the instance of the attribute on the class level in the att object.
    att = (DeveloperAttribute) Attribute.GetCustomAttribute (t, typeof (DeveloperAttribute));
        
    if(null == att)
    {
        Console.WriteLine("No attribute in class {0}.\n", t.ToString());
    }
    else
    {
        Console.WriteLine("The Name Attribute on the class level is: {0}.", att.Name);
       Console.WriteLine("The Level Attribute on the class level is: {0}.", att.Level);
       Console.WriteLine("The Reviewed Attribute on the class level is: {0}.\n", att.Reviewed);
    }   

    //Get the method-level attributes.

    //Get all methods in this class, and put them
    //in an array of System.Reflection.MemberInfo objects.
    MemberInfo[] MyMemberInfo = t.GetMethods();

    //Loop through all methods in this class that are in the 
    //MyMemberInfo array.
    for(int i = 0; i < MyMemberInfo.Length; i++)
    {        
        att = (DeveloperAttribute) Attribute.GetCustomAttribute(MyMemberInfo[i], typeof (DeveloperAttribute));
        if(null == att)
        {
            Console.WriteLine("No attribute in member function {0}.\n" , MyMemberInfo[i].ToString());
        }
        else
        {
            Console.WriteLine("The Name Attribute for the {0} member is: {1}.", MyMemberInfo[i].ToString(), att.Name);
            Console.WriteLine("The Level Attribute for the {0} member is: {1}.", MyMemberInfo[i].ToString(), att.Level);
            Console.WriteLine("The Reviewed Attribute for the {0} member is: {1}.\n", MyMemberInfo[i].ToString(), att.Reviewed);
        }        
    }
}
Public Shared Sub GetAttribute(t As Type)
    
    Dim att As DeveloperAttribute
    
    'Get the class-level attributes.
    'Put the instance of the attribute on the class level in the att object.
    att = CType(Attribute.GetCustomAttribute(t, GetType(DeveloperAttribute)), DeveloperAttribute)
    
    If att Is Nothing Then
        Console.WriteLine("No attribute in class {0}.", t.ToString())
        Console.WriteLine()
    Else
        Console.WriteLine("The Name Attribute on the class level is: {0}.", att.Name)
        Console.WriteLine("The Level Attribute on the class level is: {0}.", att.Level)
        Console.WriteLine("The Reviewed Attribute on the class level is: {0}.", att.Reviewed)
        Console.WriteLine()
    End If
    
    'Get the method-level attributes.
    'Get all methods in this class and put them
    'in an array of System.Reflection.MemberInfo objects.
    Dim MyMemberInfo As MemberInfo() = t.GetMethods()
    
    'Loop through all methods in this class that are in the 
    'MyMemberInfo array.
    Dim i As Integer
    For i = 0 To MyMemberInfo.Length - 1
        att = CType(Attribute.GetCustomAttribute(MyMemberInfo(i), GetType(DeveloperAttribute)), DeveloperAttribute)
        If att Is Nothing Then
            Console.WriteLine("No attribute in member function {0}.", MyMemberInfo(i).ToString())
            Console.WriteLine()
        Else
            Console.WriteLine("The Name Attribute for the {0} member is: {1}.", MyMemberInfo(i).ToString(), att.Name)
            Console.WriteLine("The Level Attribute for the {0} member is: {1}.", MyMemberInfo(i).ToString(), att.Level)
            Console.WriteLine("The Reviewed Attribute for the {0} member is: {1}.", MyMemberInfo(i).ToString(), att.Reviewed)
            Console.WriteLine()
        End If
    Next i
End Sub

في حالة عدم العثور علي المثيلات DeveloperAttribute على مستوي الأسلوب أو علي مستوي الفئة ، يقوم الأسلوب GetAttribute بإعلام المستخدم انه لم يتم العثور على سمات ويعرض اسم الأسلوب أو يعرض أن الفئة لا تحتوي على السمة. إذا تم العثور على سمة ,سيتم عرض الحقول Name و Level و Reviewed إلى وحدة التحكم.

يمكنك استخدام أعضاء الفئة Type للحصول على الأساليب الفردية و الأعضاء في الفئة التي تم المرور بها. يستعلم هذا المثال أولاً عن الكائن نوع للحصول على المعلومات لمستوى الفئة. بعد ذلك، يستخدم Type.GetMethods لوضع مثيلات من كافة الأساليب في مصفوفات من الكائنات System.Reflection.MemberInfo لاسترداد معلومات السمة علي مستوي الأسلوب. يمكنك أيضاً استخدام أسلوب Type.GetProperties للتحقق من السمات على مستوى الخاصية أو Type.GetConstructors للتحقق من سمات على مستوى الدالة الإنشائية.

راجع أيضًا:

المرجع

System.Type

Attribute.GetCustomAttribute

Attribute.GetCustomAttributes

المبادئ

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