특성에 저장된 정보 검색

사용자 지정 특성 검색은 간단한 프로세스입니다. 먼저, 검색하려는 특성의 인스턴스를 선언합니다. 그런 다음, Attribute.GetCustomAttribute 메서드를 사용하여 검색하려는 특성 값으로 새 특성을 초기화합니다. 새 특성이 초기화되면 그 속성을 사용하여 값을 가져오기면 됩니다.

중요

이 문서에서는 실행 컨텍스트에 로드된 코드에 대한 특성을 검색하는 방법을 설명합니다. 리플렉션 전용 컨텍스트에 로드 된 코드의 특성을 검색 하려면 다음과 같이 CustomAttributeData 클래스 를 사용 해야 합니다. 어셈블리를 리플렉션 전용 컨텍스트에로드 합니다.

이 섹션에서는 특성을 검색하는 다음 방법에 대해 설명합니다.

특성의 단일 인스턴스 검색

다음 예제에서 DeveloperAttribute(이전 섹션에 설명되어 있음)는 클래스 수준의 MainApp 클래스에 적용됩니다. GetAttribute 메서드는 클래스 수준의 DeveloperAttribute에 저장된 값을 콘솔에 표시하기 전에 먼저 GetCustomAttribute를 사용하여 검색합니다.

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);
        }
    }
};
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);
        }
    }
}
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

이전 프로그램을 실행하면 다음 텍스트가 표시됩니다.

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)
    {
        array<DeveloperAttribute^>^ MyAttributes =
            (array<DeveloperAttribute^>^) Attribute::GetCustomAttributes(t, DeveloperAttribute::typeid);

        if (MyAttributes->Length == 0)
        {
            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)
{
    DeveloperAttribute[] MyAttributes =
        (DeveloperAttribute[]) Attribute.GetCustomAttributes(t, typeof (DeveloperAttribute));

    if (MyAttributes.Length == 0)
    {
        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 Shared Sub GetAttribute(t As Type)
    Dim MyAttributes() As DeveloperAttribute =
        CType(Attribute.GetCustomAttributes(t, GetType(DeveloperAttribute)), DeveloperAttribute())

    If MyAttributes.Length = 0 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

특성을 찾을 수 없는 경우 이 코드는 사용자에게 경고를 표시합니다. 특성을 찾은 경우 DeveloperAttribute의 두 인스턴스 모두에 포함된 정보가 표시됩니다.

다양한 범위에 적용된 특성의 다중 인스턴스 검색

GetCustomAttributesGetCustomAttribute 메서드는 클래스 전체를 검색하지 않고 해당 클래스 특성의 모든 인스턴스를 반환합니다. 대신, 한 번에 하나의 지정된 메서드 또는 멤버만 검색합니다. 모든 멤버에 동일한 특성이 적용된 클래스가 있는데 해당 멤버에 적용된 모든 특성의 값을 검색하려는 경우 모든 메서드 또는 멤버를 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, 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);
            }
        }
    }
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 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

메서드 수준 또는 클래스 수준에서 DeveloperAttribute의 인스턴스를 찾을 수 없는 경우 GetAttribute 메서드는 특성을 찾을 수 없음을 사용자에게 알리고 특성이 포함되지 않은 메서드 또는 클래스의 이름을 표시합니다. 특성을 찾은 경우 Name, LevelReviewed 필드가 콘솔에 표시됩니다.

Type 클래스의 멤버를 사용하여 전달된 클래스의 개별 메서드 및 멤버를 가져올 수 있습니다. 이 예제에서는 먼저 Type 개체를 쿼리하여 클래스 수준에 대한 특성 정보를 가져옵니다. 그런 다음, 메서드 수준의 특성 정보를 검색하기 위해 Type.GetMethods를 사용하여 모든 메서드의 인스턴스를 System.Reflection.MemberInfo 개체의 배열에 배치합니다. 또한 Type.GetProperties 메서드를 사용하여 속성 수준의 특성을 확인하거나 Type.GetConstructors를 사용하여 생성자 수준의 특성을 확인할 수도 있습니다.

참조