programing

사용자 지정 특성의 생성자는 언제 실행됩니까?

megabox 2023. 5. 29. 10:30
반응형

사용자 지정 특성의 생성자는 언제 실행됩니까?

그것은 언제 운영됩니까?응용 프로그램을 적용하는 각 개체에 대해 실행됩니까, 아니면 한 번만 실행됩니까?그것은 무엇을 할 수 있습니까, 아니면 행동이 제한되어 있습니까?

컨스트럭터는 언제 실행됩니까?샘플을 사용하여 테스트해 보십시오.

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("Creating MyClass instance");
        MyClass mc = new MyClass();
        Console.WriteLine("Setting value in MyClass instance");
        mc.Value = 1;
        Console.WriteLine("Getting attributes for MyClass type");
        object[] attributes = typeof(MyClass).GetCustomAttributes(true);
    }

}

[AttributeUsage(AttributeTargets.All)]
public class MyAttribute : Attribute
{
    public MyAttribute()
    {
        Console.WriteLine("Running constructor");
    }
}

[MyAttribute]
class MyClass
{
    public int Value { get; set; }
}

그리고 결과물은 무엇입니까?

Creating MyClass instance
Setting value in MyClass instance
Getting attributes for MyClass type
Running constructor

속성을 검사하기 시작하면 속성 생성자가 실행됩니다.특성은 형식의 인스턴스가 아닌 형식에서 가져옵니다.

생성자는 항상 실행됩니다.GetCustomAttributes는 호출되거나 다른 코드가 생성자를 직접 호출할 때마다 호출됩니다(그렇게 해야 할 충분한 이유가 있는 것은 아니지만 불가능하지도 않습니다).

적어도 .NET 4.0에서는 속성 인스턴스가 캐시되지 않으며, 매번 새 인스턴스가 생성됩니다.GetCustomAttributes다음을 호출:

[Test]
class Program
{
    public static int SomeValue;

    [Test]
    public static void Main(string[] args)
    {
        var method = typeof(Program).GetMethod("Main");
        var type = typeof(Program);

        SomeValue = 1;

        Console.WriteLine(method.GetCustomAttributes(false)
            .OfType<TestAttribute>().First().SomeValue);
        // prints "1"

        SomeValue = 2;

        Console.WriteLine(method.GetCustomAttributes(false)
            .OfType<TestAttribute>().First().SomeValue);
        // prints "2"

        SomeValue = 3;

        Console.WriteLine(type.GetCustomAttributes(false)
            .OfType<TestAttribute>().First().SomeValue);
        // prints "3"

        SomeValue = 4;

        Console.WriteLine(type.GetCustomAttributes(false)
            .OfType<TestAttribute>().First().SomeValue);
        // prints "4"

        Console.ReadLine();
    }
}

[AttributeUsage(AttributeTargets.All)]
class TestAttribute : Attribute
{
    public int SomeValue { get; private set; }

    public TestAttribute()
    {
        SomeValue = Program.SomeValue;
    }
}

물론 속성이 이렇게 작동하는 것은 최선의 생각이 아닙니다.적어도 주의해야 할 것은GetCustomAttributes는 이와 같이 동작하도록 문서화되어 있지 않습니다. 실제로 위 프로그램에서 수행되는 작업은 설명서에 명시되어 있지 않습니다.

특성 생성자 내부에 디버거 중단점을 설정하고 이러한 특성을 읽는 반사 코드를 작성합니다.속성 개체는 재감염 API에서 반환될 때까지 생성되지 않습니다.속성은 클래스별입니다.그것들은 메타 데이터의 일부입니다.

이것을 확인해 보십시오.

Program.cs

using System;
using System.Linq;
[My(15)]
class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("Program started");
        var ats =
            from a in typeof(Program).GetCustomAttributes(typeof(MyAttribute), true)
            let a2 = a as MyAttribute
            where a2 != null
            select a2;

        foreach(var a in ats)
            Console.WriteLine(a.Value);

        Console.WriteLine("Program ended");
        Console.ReadLine();
    }
}

MyAttribute.cs

using System;
[AttributeUsage(validOn : AttributeTargets.Class)]
public class MyAttribute : Attribute
{
    public MyAttribute(int x)
    {
        Console.WriteLine("MyAttribute created with {0}.", x);
        Value = x;
    }

    public int Value { get; private set; }    
}

결과

Program started
MyAttribute created with 15.
15
Program ended

그러나 속성 생성자의 성능에 대해서는 걱정하지 마십시오.그것들은 반사의 가장 빠른 부분입니다 :-P

실행 파일 또는 DLL 저장소의 메타데이터:

  • 호출할 생성자를 나타내는 메타데이터 토큰
  • 그 주장들은

CLI 구현의 해당 섹션에 도달하면 처음으로 생성자를 호출할 계획입니다.GetCustomAttributes()에 대한 요청이 있습니다.ICustomAttributeProvider특정 속성 유형이 요청된 경우 해당 유형을 반환하는 데 필요한 속성만 구성합니다.

언급URL : https://stackoverflow.com/questions/1168535/when-is-a-custom-attributes-constructor-run

반응형