Take, for instance, ObsoleteAttribute: this attribute, innocently enough, behaves like any other custom attribute. It is written into the compiled metadata for your assembly. It can be reflected at runtime. But, as you know, it also triggers a specific response in the compiler; it generates a warning or error informing the programmer that the marked element is deprecated.
This can generate a false conception for the developer that attributes are instantiated a compile-time by the compiler. This is not true; ObsoleteAttribute just happens to be a special case handled specifically by the compiler.
You should also be aware of a type of attribute known as a "pseudo-attribute." These attributes are not written to the compiled metadata for your assembly, and thus cannot be reflected at runtime. Again, they are typically interpreted by the compiler in some way.
For example, there is the pseudo-attribute AssemblyVersionAttribute. This attribute tells the compiler what version to assign to the final assembly produced. If you attempt to reflect this attribute at runtime, you will find that it doesn't actually exist on your assembly (you have to use Assembly.GetName().Version).
The ultimate thing you have to keep in mind is that attributes are not instantiated until someone requests them. The compiler does this on its own in certain cases, but for the most part it just does a compile-time verification of the code and then passes the attribute on as meta-data into the IL.
For an example, assume that we have defined a custom attribute called TimeStampAttribute that takes a single string in its constructor that it wants to parse into a DateTime value. We want to use this to mark when we created certain methods:
C#:
[TimeStamp("fred")]
public void MyMethod()
{
// ...
}
VB.NET:
<TimeStamp("fred")> _
Public Sub MyMethod()
' ...
End Sub
But wait! That code won't work, right? It's supposed to have a date/time that we can parse like "1/24/2007 11:46 PM" instead of "fred." We're going to get a FormatException as soon as we run, right? Wrong.
The code of course compiles just fine, since "fred" is a string like we asked for. The code will even run just fine for the most part since the attributes aren't created explicitly. You won't get the expected exception raised until you make a call to GetCustomAttributes() that ends up iterating over the attributes in question.
No comments:
Post a Comment