检索存储在特性中的信息

检索自定义特性的过程很简单。 首先,声明要检索的特性实例。 然后,使用 Attribute.GetCustomAttribute 方法将新特性初始化为要检索的特性值。 初始化新特性后,只需使用其属性获取值即可。

重要说明重要事项

本主题描述如何检索已加载到执行上下文中的代码的特性。若要检索已加载到只反射上下文中的代码的特性,必须使用 CustomAttributeData 类,如如何:将程序集加载到仅反射上下文中所示。

本节描述下列检索特性的方法:

  • 检索特性的一个实例

  • 检索应用到同一范围的特性的多个实例

  • 检索应用到不同范围的特性的多个实例

检索特性的一个实例

在下面的示例中,DeveloperAttribute(详见前一节的介绍)应用到类级别上的 MainApp 类。 GetAttribute 方法使用 GetCustomAttribute 检索存储在类级别上 DeveloperAttribute 中的值,然后将这些值显示到控制台。

Imports System
Imports System.Reflection
Imports CustomCodeAttributes

<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
using System;
using System.Reflection;
using CustomCodeAttributes;

[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 (MyAttribute == null)
        {
            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);
        }
    }
}
using namespace System;
using namespace System::Reflection;
using namespace CustomCodeAttributes;

[Developer("Joan Smith", "42", Reviewed = true)]
ref class MainApp
{
public:
    static void Main()
    {
        // Call function to get and display the attribute.
        GetAttribute(MainApp::typeid);
    }

    static void GetAttribute(Type^ t)
    {
        // Get instance of the attribute.
        DeveloperAttribute^ MyAttribute =
            (DeveloperAttribute^) Attribute::GetCustomAttribute(t, DeveloperAttribute::typeid);

        if (MyAttribute == nullptr)
        {
            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);
        }
    }
};

该程序在执行时显示下列文本。

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

如果未找到该特性,则 GetCustomAttribute 方法将 MyAttribute 初始化为一个 null 值。 该示例检查 MyAttribute 以查找这样的实例,如未找到任何特性,则通知用户。 如果在类范围中未找到 DeveloperAttribute,则下列消息将显示到控制台。

The attribute was not found. 

该示例假定特性定义位于当前命名空间中。 如果特性定义不在当前命名空间中,请务必导入该特性定义所驻留的命名空间。

检索应用到同一范围的特性的多个实例

在前一个示例中,要检查的类和要查找的特定特性被传递到 GetCustomAttribute。 如果类级别上只应用特性的一个实例,则该代码将运行良好。 但是,如果在同一类级别上应用特性的多个实例,则 GetCustomAttribute 方法不检索所有信息。 如果同一个特性的多个实例应用到相同的范围,可使用 Attribute.GetCustomAttributes 将特性的所有实例放到一个数组中。 例如,如果在同一个类的类级别上应用 DeveloperAttribute 的两个实例,则可修改 GetAttribute 方法以显示同时存在于这两个特性中的信息。 请记住,若要在同一级别上应用多个特性,必须在定义该特性时在 AttributeUsageAttribute 中将 AllowMultiple 属性设置为 true

下面的代码示例说明如何使用 GetCustomAttributes 方法创建在任意给定类中引用 DeveloperAttribute 的所有实例的数组。 然后,所有特性的值将显示到控制台。

Public Shared Sub GetAttribute(t As Type)
    Dim MyAttributes() As DeveloperAttribute =
        CType(Attribute.GetCustomAttributes(t, GetType(DeveloperAttribute)), DeveloperAttribute())

    If MyAttributes Is Nothing Then
        Console.WriteLine("The attribute was not found.")
    Else
        For i As Integer = 0 To MyAttributes.Length - 1
            ' Get the Name value.
            Console.WriteLine("The Name Attribute is: {0}." , MyAttributes(i).Name)
            ' Get the Level value.
            Console.WriteLine("The Level Attribute is: {0}." , MyAttributes(i).Level)
            ' Get the Reviewed value.
            Console.WriteLine("The Reviewed Attribute is: {0}.", MyAttributes(i).Reviewed)
        Next i
    End If
End Sub
public static void GetAttribute(Type t)
{
    DeveloperAttribute[] MyAttributes =
        (DeveloperAttribute[]) Attribute.GetCustomAttributes(t, typeof (DeveloperAttribute));

    if (MyAttributes == null)
    {
        Console.WriteLine("The attribute was not found.");
    }
    else
    {
        for (int i = 0 ; i < MyAttributes.Length ; i++)
        {
            // Get the Name value.
            Console.WriteLine("The Name Attribute is: {0}." , MyAttributes[i].Name);
            // Get the Level value.
            Console.WriteLine("The Level Attribute is: {0}." , MyAttributes[i].Level);
            // Get the Reviewed value.
            Console.WriteLine("The Reviewed Attribute is: {0}.", MyAttributes[i].Reviewed);
        }
    }
}
public:
    static void GetAttribute(Type^ t)
    {
        array<DeveloperAttribute^>^ MyAttributes =
            (array<DeveloperAttribute^>^) Attribute::GetCustomAttributes(t, DeveloperAttribute::typeid);

        if (MyAttributes == nullptr)
        {
            Console::WriteLine("The attribute was not found.");
        }
        else
        {
            for (int i = 0 ; i < MyAttributes->Length; i++)
            {
                // Get the Name value.
                Console::WriteLine("The Name Attribute is: {0}." , MyAttributes[i]->Name);
                // Get the Level value.
                Console::WriteLine("The Level Attribute is: {0}." , MyAttributes[i]->Level);
                // Get the Reviewed value.
                Console::WriteLine("The Reviewed Attribute is: {0}.", MyAttributes[i]->Reviewed);
            }
        }
    }

如果没有找到任何特性,该代码将提醒用户。 否则,将显示两个 DeveloperAttribute 实例中都包含的信息。

检索应用到不同范围的特性的多个实例

GetCustomAttributes 方法和 GetCustomAttribute 方法不搜索整个类和返回该类中某个特性的所有实例。 相反,它们一次只搜索一个指定方法或成员。 如果将具有同一特性的某个类应用到每个成员,并要检索应用到这些成员的所有特性值,则必须向 GetCustomAttributesGetCustomAttribute 分别提供每个方法或成员。

下面的代码示例将类用作参数,并在类级别上以及该类的每个方法上搜索 DeveloperAttribute(先前已定义)。

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
        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)
    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.
    For i As Integer = 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}.\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)
        End If
    Next
End Sub
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 (att == null)
    {
        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 (att == null)
        {
            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:
    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, DeveloperAttribute::typeid);

        if (att == nullptr)
        {
            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.
        array<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], DeveloperAttribute::typeid);
            if (att == nullptr)
            {
                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);
            }
        }
    }

如果在方法级别或类级别上未找到 DeveloperAttribute 的任何实例,GetAttribute 方法将通知用户未找到任何特性,并显示不包含该特性的方法或类的名称。 如果找到了特性,则控制台将显示 Name、Level 和 Reviewed 字段。

可使用 Type 类的成员获取已传递的类中的各个方法和成员。 该示例首先查询 Type 对象以获取类级别的特性信息。 然后使用 Type.GetMethods 将所有方法的实例放到 System.Reflection.MemberInfo 对象的一个数组中以检索方法级别的特性信息。 您也可以使用 Type.GetProperties 方法检查属性级别上的特性,或使用 Type.GetConstructors 方法检查构造函数级别上的特性。

请参见

参考

System.Type

Attribute.GetCustomAttribute

Attribute.GetCustomAttributes

概念

利用特性扩展元数据