AddThis Social Bookmark Button

Print

Programming C#: Attributes and Reflection
Pages: 1, 2, 3, 4, 5, 6, 7, 8, 9

Attributes

An attribute is an object that represents data you want to associate with an element in your program. The element to which you attach an attribute is referred to as the target of that attribute. For example, the attribute:



[NoIDispatch]

is associated with a class or an interface to indicate that the target class should derive from IUnknown rather than IDispatch, when exporting to COM. COM interface programming is discussed in detail in Chapter 22.

In Chapter 17, you saw this attribute:

[assembly: AssemblyKeyFile("c:\myStrongName.key")]

This inserts metadata into the assembly to designate the program's StrongName.

Intrinsic Attributes

Attributes come in two flavors: intrinsic and custom. Intrinsic attributes are supplied as part of the Common Language Runtime (CLR), and they are integrated into .NET. Custom attributes are attributes you create for your own purposes.

Most programmers will use only intrinsic attributes, though custom attributes can be a powerful tool when combined with reflection, described later in this chapter.

Attribute Targets

If you search through the CLR, you'll find a great many attributes. Some attributes are applied to an assembly, others to a class or interface, and some, such as [WebMethod], to class members. These are called the attribute targets. Possible attribute targets are detailed in Table 18-1.

Table 18-1: Possible attribute targets

Member Name

Usage

All

Applied to any of the following elements: assembly, class, class member, delegate, enum, event, field, interface, method, module, parameter, property, return value, or struct

Assembly

Applied to the assembly itself

Class

Applied to instances of the class

ClassMembers

Applied to classes, structs, enums, constructors, methods, properties, fields, events, delegates, and interfaces

Constructor

Applied to a given constructor

Delegate

Applied to the delegated method

Enum

Applied to an enumeration

Event

Applied to an event

Field

Applied to a field

Interface

Applied to an interface

Method

Applied to a method

Module

Applied to a single module

Parameter

Applied to a parameter of a method

Property

Applied to a property (both get and set, if implemented)

ReturnValue

Applied to a return value

Struct

Applied to a struct

Applying Attributes

You apply attributes to their targets by placing them in square brackets immediately before the target item. You can combine attributes, either by stacking one on top of another:

[assembly: AssemblyDelaySign(false)]
[assembly: AssemblyKeyFile(".\\keyFile.snk")]

or by separating the attributes with commas:

[assembly: AssemblyDelaySign(false),
   assembly: AssemblyKeyFile(".\\keyFile.snk")]

TIP: You must place assembly attributes after all using statements and before any code.

Many intrinsic attributes are used for interoperating with COM, as discussed in detail in Chapter 22. You've already seen use of one attribute ([WebMethod]) in Chapter 16. You'll see other attributes, such as the [Serializable] attribute, used in the discussion of serialization in Chapter 19.

The System.Runtime namespace offers a number of intrinsic attributes, including attributes for assemblies (such as the keyname attribute), for configuration (such as debug to indicate the debug build), and for version attributes.

You can organize the intrinsic attributes by how they are used. The principal intrinsic attributes are those used for COM, those used to modify the Interface Definition Language (IDL) file from within a source-code file, attributes used by the ATL Server classes, and attributes used by the Visual C++ compiler.

Perhaps the attribute you are most likely to use in your everyday C# programming (if you are not interacting with COM) is [Serializable]. As you'll see in Chapter 19, all you need to do to ensure that your class can be serialized to disk or to the Internet is add the [Serializable] attribute to the class:

[serializable]
class MySerializableClass

The attribute tag is put in square brackets immediately before its target--in this case, the class declaration.

The key fact about intrinsic attributes is that you know when you need them; the task will dictate their use.

Custom Attributes

You are free to create your own custom attributes and use them at runtime as you see fit. Suppose, for example, that your development organization wants to keep track of bug fixes. You already keep a database of all your bugs, but you'd like to tie your bug reports to specific fixes in the code.

You might add comments to your code along the lines of:

// Bug 323 fixed by Jesse Liberty 1/1/2005.

This would make it easy to see in your source code, but there is no enforced connection to Bug 323 in the database. A custom attribute might be just what you need. You would replace your comment with something like this:

[BugFixAttribute(323,"Jesse Liberty","1/1/2005")
Comment="Off by one error"]

You could then write a program to read through the metadata to find these bug-fix notations and update the database. The attribute would serve the purposes of a comment, but would also allow you to retrieve the information programmatically through tools you'd create.

Pages: 1, 2, 3, 4, 5, 6, 7, 8, 9

Next Pagearrow