When does an attribute constructor get called?
There seams to be two likely places that attribute constructor would be called:
1) Around the static constructor fo the type the attribute is defined on or in.
2) At the time you reflect over the object to find the attributes.
The test attribute looks like this:
public class MyAttribute : Attribute
{
public MyAttribute()
{
Console.WriteLine("In Attribute Constructor");
}
}
To test theory #1 the code looks like this:
[My]
class Program
{
static void Main(string[] args)
{
Console.WriteLine("In main");
}
}
The results: The attribute constructor isn't called.
So now we need to make sure it really is theory #2:
[My]
class Program
{
static void Main(string[] args)
{
Console.WriteLine("In main");
typeof(Program).GetCustomAttributes(true);
}
}
As expected this causes the attribute constructor to be called. Which raises a follow up question, if we just look for some other type of attribute, say just Obsolete attributes, will our attribute still get constructed?
[My]
class Program
{
static void Main(string[] args)
{
Console.WriteLine("In main");
typeof(Program).GetCustomAttributes(typeof(ObsoleteAttribute),true);
}
}
Interestingly enough this does not cause our constructor to be called. So the moral of the story is that an attribute will be lazily constructed.
Why is this interesting? I ran into this question because I was creating an attribute that expired, so one of the parameters to the constructor would be a date, and in the constructor of the attribute it would throw an exception if that date had passed. This behavior was going to be used to make sure if we ignored unit tests they had to eventually be turned back on. So I wanted to see when exactly we could expect this exception to be called. And it turns out to only be when you ask the type about this attribute.
1 comments:
great post! I was reading about the serializable attribute yesterday and could not wrap my head around the difference between using [serializable] and using [serializable()]. Is there a reason to use one or the other?
Thanks!
Post a Comment