IT TIP

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

itqueen 2020. 10. 24. 12:07
반응형

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


언제 실행 되나요? 적용 할 각 개체에 대해 실행됩니까, 아니면 한 번만 실행됩니까? 무엇이든 할 수 있습니까? 아니면 행동이 제한됩니까?


생성자는 언제 실행됩니까? 샘플을 사용해보십시오.

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

It is not the best idea to have attributes behave like this, of course. At the very least, note that GetCustomAttributes is not documented to behave like this; in fact, what happens in the above program is not specified in the documentation.


Set a debugger break-point inside an attribute constructor and write some reflection code that reads those attributes. You'll notice that the attribute objects won't be created until they are returned from the relfection API. Attributes are per class. They are part of the meta data.

Have a look at this:

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

Result

Program started
MyAttribute created with 15.
15
Program ended

But don't worry about the performance of attribute constructors. They are the fastest part of reflection :-P


The metadata in the executable or DLL stores:

  • A metadata token indicating the constructor to call
  • The arguments

When I get to that section of my CLI implementation, I plan to lazy-call the constructor the first time GetCustomAttributes() is called for the ICustomAttributeProvider. If a particular attribute type is requested, I'll only construct the ones required to return that type.

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

반응형