Attributes


The ability to reflect methods and type information is a nice and intriguing technology, but reflection really shines and demonstrates its value when you use it in conjunction with .NET attributes. The idea behind attributes is simple: instead of coding functionality and features into your objects, you can add them by decorating your objects with attributes. The information in the attributes is added to the metadata about the objects that the compiler generates (its methods, base classes, etc.). .NET (or your custom tools) can read the metadata, look for the attributes, and then perform the functionality and add the features the attributes specify without the object's or its developer's involvement. For example, when you want to combine enums in a binary masking value, you can use the Flags attribute:

     [Flags]     public enum WeekDay     {        Monday,        Tuesday,        Wednesday,        Thursday,        Friday,        Saturday,        Sunday,     }

When the compiler sees the Flags attribute, it allows you to combine enum values with the | (OR) operator, as if they were integer powers of 2. For example:

     const WeekDay Weekend = WeekDay.Saturday|WeekDay.Sunday;

Another example is the Conditional attribute, defined in the System.Diagnostics namespace. This attribute directs the compiler to exclude from a build calls to any method it decorates if a specified condition isn't defined:

     #define MySpecialCondition //usually DEBUG     public class MyClass     {        public MyClass(  )        {}        [Conditional("MySpecialCondition")]        public void MyMethod(  )        {...}     }     //Client side code     MyClass obj = new MyClass(  );     //This line is conditional          obj.MyMethod(  );

Having the compiler do the method-call exclusion automatically is, of course, a major improvement over C++ or classic VB. In the past, when developers did code exclusion manually and then wanted to reinstate the method calls, they sometimes forgot to do so somewhere and thus caused defects in the code.

Attributes are used in every aspect of .NET programming: in asynchronous calls, in object persistence and serialization, in concurrency management, in remote calls, in security, in interoperability with COM and Windows, and in Enterprise Services.

Using Attributes

An attribute is actually a class in its own right. The attribute class should have the suffix Attribute in its name, and it must derive (directly or indirectly) from the class Attribute:

     public class FlagsAttribute : Attribute     {...}

When you use attributes, you use square brackets [ ] (or angle brackets < > in Visual Basic 2005) around their names. However, the C# and Visual Basic 2005 compilers support a shorthand when using an attribute. If the attribute name ends with Attribute, the compiler lets you omit the Attribute suffix:

     [Flags] //same as [FlagsAttribute]     public enum Color     {        Red,Green,Blue,Purple = Red | Blue     }

You can stack as many attributes as you like on a type or a type member, as long as the attributes don't contradict each other. However, you can't apply any attribute to any type or type member. Each attribute has an attribute of type AttributeUsage associated with it that dictates which types (class, interface, enum, etc.), and which syntactic elements (constructor, method, parameter, returned value, etc.) the attribute is applicable to. AttributeUsage also dictates whether the attribute can be used multiple times on the same target. (You will learn more about AttributeUsage in the next section.) Attributes can also have a default constructor and can accept construction parameters. If a default constructor is available, you can use the attribute with or without parentheses:

     [MyAttribute(  )] //same as [MyAttribute]

Attributes can accept construction parameters and have public properties that you can set. If you have both parameterized constructors and properties, you must specify the parameters to the constructor before setting the properties. There are limitations on the types of parameters the attribute constructors and properties can accept; for instance, they can't accept a class or struct as a parameter. The only permissible reference types are array, Type, and object.

Kinds of Attributes

There are three kinds of attributes in .NET. First, there are standard attributes, such as Flags and Conditional. Standard attributes are available in .NET out of the box. The .NET compilers and runtime know about these attributes and obey their directions. The second kind of attributes are custom attributes, which are attributes you provide. These go completely unnoticed by .NET, expect that the compiler adds them as part of the metadata. As discussed in the next section, you have to write the reflection code to make sense of the custom attributes. Such attributes usually have domain-specific semantics. The third kind of attributes are custom context attributes. Both .NET and you can provide custom context attributes. .NET is fully aware of them and will comply with their directions and influence the decorated objects accordingly. Chapter 11 discusses context attributes at length.



Programming. NET Components
Programming .NET Components, 2nd Edition
ISBN: 0596102070
EAN: 2147483647
Year: 2003
Pages: 145
Authors: Juval Lowy

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