사용자 지정 특성 액세스

특성이 프로그램 요소와 연결된 후 리플렉션을 사용하여 특성의 존재 및 값을 쿼리할 수 있습니다. .NET은 실행을 위해 로드할 수 없는 코드를 검사하는 데 사용할 수 있는 기능을 제공합니다 MetadataLoadContext.

MetadataLoadContext

컨텍스트에 로드된 코드는 MetadataLoadContext 실행할 수 없습니다. 즉, 생성자를 실행할 필요가 없으므로 사용자 지정 특성의 인스턴스를 만들 수 없습니다. 컨텍스트에서 MetadataLoadContext 사용자 지정 특성을 로드하고 검사하려면 클래스를 CustomAttributeData 사용합니다. static CustomAttributeData.GetCustomAttributes 메서드의 적절한 오버로드를 사용하여 이 클래스의 인스턴스를 가져올 수 있습니다. 자세한 내용은 방법: MetadataLoadContext를 사용하여 어셈블리 콘텐츠 검사를 참조하세요.

실행 컨텍스트

실행 컨텍스트에서 특성을 쿼리하는 기본 리플렉션 메서드는 MemberInfo.GetCustomAttributesAttribute.GetCustomAttributes입니다.

사용자 지정 특성의 접근성은 연결된 어셈블리와 관련하여 검사. 이 확인은 사용자 지정 특성이 연결된 어셈블리의 형식에 대한 메서드가 사용자 지정 특성의 생성자를 호출할 수 있는지 확인하는 것과 같습니다.

Assembly.GetCustomAttributes(Boolean) 같은 메서드는 형식 인수의 표시 유형 및 접근성을 확인합니다. 사용자 정의 형식이 포함된 어셈블리의 코드만 .를 사용하여 GetCustomAttributes해당 형식의 사용자 지정 특성을 검색할 수 있습니다.

다음 C# 예제는 일반적인 사용자 지정 특성 디자인 패턴입니다. 이 예제는 런타임 사용자 지정 특성 리플렉션 모델을 보여 줍니다.

System.DLL
public class DescriptionAttribute : Attribute
{
}

System.Web.DLL
internal class MyDescriptionAttribute : DescriptionAttribute
{
}

public class LocalizationExtenderProvider
{
    [MyDescriptionAttribute(...)]
    public CultureInfo GetLanguage(...)
    {
    }
}

런타임이 메서드에 연결된 공용 사용자 지정 특성 형식 DescriptionAttribute 에 대한 사용자 지정 특성을 검색하려고 하면 GetLanguage 다음 작업을 수행합니다.

  1. 런타임은 형식 인수 DescriptionAttributeType.GetCustomAttributes(Type type) 가 공용이므로 표시되고 액세스할 수 있는 검사.
  2. 런타임은 파생된 DescriptionAttribute 사용자 정의 형식 MyDescriptionAttribute 이 메서드GetLanguage()에 연결된 System.Web.dll 어셈블리 내에서 표시되고 액세스할 수 있음을 검사.
  3. 런타임은 생성자가 MyDescriptionAttribute System.Web.dll 어셈블리 내에서 표시되고 액세스할 수 있는지 검사.
  4. 런타임은 사용자 지정 특성 매개 변수를 사용하여 생성자를 MyDescriptionAttribute 호출하고 새 개체를 호출자에게 반환합니다.

사용자 지정 특성 리플렉션 모델에서는 형식이 정의된 어셈블리 외부에서 사용자 정의 형식의 인스턴스가 누수될 수 있습니다. 이는 개체 배열 반환과 같이 Type.GetMethods 사용자 정의 형식의 인스턴스를 반환하는 런타임 시스템 라이브러리의 RuntimeMethodInfo 멤버와 다르지 않습니다. 클라이언트가 사용자 정의 사용자 지정 특성 유형 관련 정보를 검색하지 않게 하려면 유형의 멤버를 public이 아닌 멤버로 정의합니다.

다음 예제에서는 리플렉션을 사용하여 사용자 지정 특성에 대한 액세스 권한을 얻는 기본적인 방법을 보여 줍니다.

using namespace System;

public ref class ExampleAttribute : Attribute
{
private:
    String^ stringVal;

public:
    ExampleAttribute()
    {
        stringVal = "This is the default string.";
    }


    property String^ StringValue
    {
        String^ get() { return stringVal; }
        void set(String^ value) { stringVal = value; }
    }
};

[Example(StringValue="This is a string.")]
public ref class Class1
{
public:
    static void Main()
    {
        System::Reflection::MemberInfo^ info = Type::GetType("Class1");
        for each (Object^ attrib in info->GetCustomAttributes(true))
        {
            Console::WriteLine(attrib);
        }
    }
};

int main()
{
    Class1::Main();
}
using System;

public class ExampleAttribute : Attribute
{
    private string stringVal;

    public ExampleAttribute()
    {
        stringVal = "This is the default string.";
    }

    public string StringValue
    {
        get { return stringVal; }
        set { stringVal = value; }
    }
}

[Example(StringValue="This is a string.")]
class Class1
{
    public static void Main()
    {
        System.Reflection.MemberInfo info = typeof(Class1);
        foreach (object attrib in info.GetCustomAttributes(true))
        {
            Console.WriteLine(attrib);
        }
    }
}
Public Class ExampleAttribute
    Inherits Attribute

    Private stringVal As String

    Public Sub New()
        stringVal = "This is the default string."
    End Sub

    Public Property StringValue() As String
        Get
            Return stringVal
        End Get
        Set(Value As String)
            stringVal = Value
        End Set
    End Property
End Class

<Example(StringValue:="This is a string.")> _
Class Class1
    Public Shared Sub Main()
        Dim info As System.Reflection.MemberInfo = GetType(Class1)
        For Each attrib As Object In info.GetCustomAttributes(true)
            Console.WriteLine(attrib)
        Next attrib
    End Sub
End Class

참고 항목