检索存储在属性中的信息

更新:2007 年 11 月

检索自定义属性的过程很简单。首先,声明要检索的属性实例。然后,使用 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 初始化为一个 null 值。该示例检查 MyAttribute 以查找这样的实例,如未找到任何属性,则通知用户。如果在类范围中未找到 DeveloperAttribute,则下列消息将显示到控制台。

The attribute was not found. 

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

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

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

下面的代码示例说明如何使用 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 方法不搜索整个类和返回该类中某个属性的所有实例。相反,它们一次只搜索一个指定方法或成员。如果将具有同一属性的某个类应用到每个成员,并要检索应用到这些成员的所有属性值,则必须向 GetCustomAttributesGetCustomAttribute 分别提供每个方法或成员。

下面的代码示例将类用作参数,并在类级别上以及该类的每个方法上搜索 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 对象以获取类级别的属性信息。然后使用 Type.GetMethods 将所有方法的实例放到 System.Reflection.MemberInfo 对象的一个数组中以检索方法级别的属性信息。您也可以使用 Type.GetProperties 方法检查属性 (Property) 级别上的属性 (Attribute),或使用 Type.GetConstructors 方法检查构造函数级别上的属性 (Attribute)。

请参见

参考

System.Type

Attribute.GetCustomAttribute

Attribute.GetCustomAttributes

其他资源

利用属性扩展元数据