C Sharp

Class Attributes

How you retrieve an attribute depends on the member type being queried. Let's say you want to define an attribute that will define the remote server on which an object is to be created. Without attributes, you'd save this information in a constant or in the application's resource file. Using attributes, you can simply annotate the class with its remote server like this: -

using System;
public enum RemoteServers
{
    JEANVALJEAN,
    JAVERT,
    COSETTE
}
public class RemoteObjectAttribute : Attribute
{
    public RemoteObjectAttribute(RemoteServers Server)
    {
        this.server = Server;
    }
    protected RemoteServers server;
    public string Server
    {
        get
        {
            return RemoteServers.GetName(typeof(RemoteServers),
                                         this.server);
        }
    }
}
[RemoteObject(RemoteServers.COSETTE)]
class MyRemotableClass
{
}

To determine the server on which to create the object, use code like the following: -

class ClassAttrApp
{
    public static void Main()
    {
        Type type = typeof(MyRemotableClass);
        foreach (Attribute attr in type.GetCustomAttributes())
        {
            RemoteObjectAttribute remoteAttr =
                attr as RemoteObjectAttribute;
            if (null != remoteAttr)
            {
                Console.WriteLine("Create this object on {0}.",
                                  remoteAttr.Server);
            }
        }
    }
}

As you might expect, the output from this application is the following: -

Create this object on COSETTE.

Because all variations of this example will use some common code, let's examine what's going on here regarding reflection and how it returns the attribute's value at run time.

The first line you'll notice in the Main method is the use of the typeof operator: -

Type type = typeof(MyRemotableClass);

This operator returns the System.Type object associated with the type that is passed as its only argument. Once you have that object, you can start to query it.

There are two parts to explain about the next line of code: -

foreach (Attribute attr in type.GetCustomAttributes(true))

The first is the call to the Type.GetCustomAttributes method. This method returns an array of type Attribute that in this case will contain all the attributes attached to the class named MyRemotableClass. The second is the foreach statement, which iterates the return array, stuffing each successive value into a variable (attr) of type Attribute.

The next statement uses the as operator to attempt to convert the attr variable to a type of RemoteObjectAttribte: -

RemoteObjectAttribute remoteAttr =
        attr as RemoteObjectAttribute;

We then test for a null value, the result of a failed case via the as operator. If the value is not null-meaning that the remoteAttr variable holds a valid attribute attached to the MyRemotableClass type-we call one of the RemoteObjectAttribute properties to print the remote server name: -

if (null != remoteAttr)
{
    Console.WriteLine("Create this object on {0}",
                      remoteAttr.Server);
}