0

According to here, attribute constructor will not run until GetCustomAttributes() method is called. This will instantiate every attributes owned the class. What is the most efficient way to force construct a certain custom attribute ? Upon new-ing the class, I only want to instantiate specific attributes, not all of them.

[RegularAttribute("Dont_turn_me_on_yet")]
public class MyClass
{
    public int Value { get; set; }

    [SpecialAttribute("On_RightAway_Please")]
    public void MethodOne(){}

    [RegularAttribute("Dont_turn_me_on_yet")]
    public void MethodTwo(){}
}

static void Main()
{
   var mc = new MyClass(); //SpecialAttribute constructor is called right away, but not RegularAttribute
}
Community
  • 1
  • 1
Jeson Martajaya
  • 6,996
  • 7
  • 54
  • 56

2 Answers2

0

You're misunderstanding what attributes are. Attributes are metadata, they're stored in the assembly as a kind of recipe for an object:

  • Used attribute's constructor metadata token
  • Positional parameters' values
  • Property setters values

That's it. No more, no less.

When you call GetCustomAttributes on a member, the runtime will instantiate this member's attributes with the recipe stored in the metadata, and handle you that.

You get a fresh instance on each call, as attribute instance are just classes, and therefore are mutable. Doing so ensures you get the true metadata. If you have performance issues with this, just cache them yourself, and make sure you don't alter them.

Lucas Trzesniewski
  • 50,214
  • 11
  • 107
  • 158
  • Right. Thank you for the theory behind it. I am looking for a way to work around it. It is similar to the way Microsoft does it with their CAB's EventBroker subscription. http://blogs.msdn.com/b/edjez/archive/2005/04/20/cabeventbroker101.aspx – Jeson Martajaya Oct 24 '15 at 22:19
  • They don't do it magically either: *"The attributes are there for simplifying the dev experience - they get processed **whenever an instance of the class that has them gets added to a WorkItem or the Host** in CAB."*. While you could design a base class which would instantiate the attributes of its derived class upon its construction, I think you've got a [XY problem](http://meta.stackexchange.com/a/66378/271659) here. – Lucas Trzesniewski Oct 25 '15 at 10:23
0

Found the answer. GetCustomAttributes is able to get certain attributes by type. This code below will not instantiate the RegularAttribute. It needs to be called in either base constructor or `[InjectionMethod] in Unity DI.

MethodInfo[] methods = (typeof(MyClass)).GetMethods();
foreach (var method in methods)
{
    var attribute = method.GetCustomAttributes(typeof(SpecialAttributeAttribute), false);
}

More efficient answer is welcomed.

Jeson Martajaya
  • 6,996
  • 7
  • 54
  • 56