다음을 통해 공유


특성에 저장된 정보 검색

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

중요하다

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

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

특성의 단일 인스턴스 검색

다음 예제에서는 이전 섹션에서 설명한 DeveloperAttribute가 클래스 수준에서 MainApp 클래스에 적용됩니다. GetAttribute 메서드는 GetCustomAttribute 사용하여 클래스 수준에서 DeveloperAttribute 저장된 값을 검색한 후 콘솔에 표시합니다.

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 생성자 수준에서 특성을 확인할 수도 있습니다.

클래스 멤버에서 특성 검색

클래스 수준에서 특성을 검색하는 것 외에도 메서드, 속성 및 필드와 같은 개별 멤버에도 특성을 적용할 수 있습니다. GetCustomAttributeGetCustomAttributes 메서드를 사용하여 이러한 특성을 검색할 수 있습니다.

본보기

다음 예제에서는 메서드에 적용된 특성을 검색하는 방법을 보여 줍니다.

using System;
using System.Reflection;

[AttributeUsage(AttributeTargets.Method)]
public class MyAttribute : Attribute
{
    public string Description { get; }
    public MyAttribute(string description) { Description = description; }
}

public class MyClass
{
    [MyAttribute("This is a sample method.")]
    public void MyMethod() { }
}

class AttributeRetrieval
{
    public static void Main()
    {
        // Create an instance of MyClass
        MyClass myClass = new MyClass();

        // Retrieve the method information for MyMethod
        MethodInfo methodInfo = typeof(MyClass).GetMethod("MyMethod");
        MyAttribute attribute = (MyAttribute)Attribute.GetCustomAttribute(methodInfo, typeof(MyAttribute));

        if (attribute != null)
        {
            // Print the description of the method attribute
            Console.WriteLine("Method Attribute: {0}", attribute.Description);
        }
        else
        {
            Console.WriteLine("Attribute not found.");
        }
    }
}

참고 항목