Searching Code for Attributes


Attributes in themselves don't do anything unless a program or the runtime looks for them. When you ask a certain type for its custom attributes, the runtime creates an instance of the attribute class and invokes one of the class's constructors. The runtime looks at the arguments of the attribute to determine which constructor to invoke. The runtime then sets the value of any of the named fields.

For the following example, assume that we're looking for custom attributes of type VisibleColumn and that these attributes can only be applied to a class's fields.

To search for custom attributes:

  1. Get a Type object for the class you wish to search. For example: System.Type typeClass = typeof(Person); where Person is the class we are inspecting.

  2. Enumerate through all the fields in the class. For example: foreach(System.Reflection.FieldInfo fi in typeClass.GetFields() ) { .

  3. Get all the custom attributes of a specific type using the GetCustomAttributes() function and passing a type object for the attribute class. The function returns an array of attributes that have been applied to the element. Normally this array will contain either zero elements or one element (since attribute by default can only be applied once to an element). You can use foreach to enumerate through the array returned by GetCustomAttributes() . For example: foreach( object attrobj in fi.GetCustomAttributes(typeof(VisibleColumnAttribute)){} .

  4. Cast the object element to the particular attribute class type so that you can examine the properties of the attribute. For example: VisibleColumnAttribute attr = (VisibleColumnAttribute) attrobj ; ( Figure 12.33 ).

    Figure 12.33 GetCustomAttributes can give an array of every type of attribute that has been applied to an element, or you can get all the attributes of a certain type as you see from the example here.
     //get a reference to our assembly //that's where we have the definition for //the Address class Assembly ad = Assembly.GetExecutingAssembly(); object objAddress = ad.CreateInstance(                   ordersystem.Address"); Type typeAddress = typeof(Address); FieldInfo fldStreet = typeAddress.GetField("SecurityCode"); //get the custom attributes for the field object[] attrs = fldStreet.  GetCustomAttributes(   typeof(Author),false)  ; //we only apply the attribute once, so it should be the first one of its type Author author1 = (Author)attrs[0]; Response.Write(author1.Name); //below are the class definitions we're //working with /* [AttributeUsage(AttributeTargets.All,AllowMul tiple=false)] class Author : System.Attribute {    public string Name;    public Author(string name)    {       Name = name;    } } class Address {    public string Street;    public string City;    public string ZipCode;    [NonSerialized,Author("Jose")]    public string SecurityCode; } */ 

graphics/tick.gif Tips

  • When you call GetCustomAttributes() the runtime creates an instance of all the attribute classes that are applied to the particular element if any. Each of the element types MethodInfo, PropertyInfo, ConstructorInfo , etc. has a GetCustomAttributes() function and invoking it only creates instances of the attributes applied to that particular element.

  • If you want to find out if an element has an attribute without having the runtime create instances of the element, you can use the IsDefined() method. This lets you input the type object for the attribute for which you are searching. It also lets you specify if inheritance should be taken into account. In other words, does the base class have this attribute? ( Figure 12.34 )

    Figure 12.34 When you call GetCustomAttributes the framework creates an instance of all the attributes that have been applied to the element. Sometimes all you want to know is if it's been applied to an element. In that case you can use the IsDefined function, which doesn't cause the framework to instantiate the attributes.
     //get a reference to our assembly //that's where we have the definition for //the Address class Assembly ad = Assembly.GetExecutingAssembly(); object objAddress = ad.CreateInstance(                  "ordersystem.Address"); Type typeAddress = typeof(Address); Bool Defined= typeAddress.  IsDefined(typeof(Serializable),false)  ; 



C#
C# & VB.NET Conversion Pocket Reference
ISBN: 0596003196
EAN: 2147483647
Year: 2003
Pages: 198
Authors: Jose Mojica

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net