C Sharp

Method Attributes

Now that we've seen how to work with class attributes, let's look at using method attributes. This discussion is a separate section because the reflection code needed to query a method attribute is different from that needed to query a class attribute. In this example, we'll use an attribute that would be used to define a method as being transactionable: -

using System;
using System.Reflection;
public class TransactionableAttribute : Attribute
{
    public TransactionableAttribute()
    {
    }
}
class TestClass
{
    [Transactionable]
    public void Foo()
    {}
    public void Bar()
    {}
    [Transactionable]
    public void Baz()
    {}
}
class MethodAttrApp
{
    public static void Main()
    {
        Type type = Type.GetType("TestClass");
        foreach(MethodInfo method in type.GetMethods())
        {
            foreach (Attribute attr in
                     method.GetCustomAttributes())
            {
                if (attr is TransactionableAttribute)
                {
                    Console.WriteLine("{0} is transactionable.",
                                      method.Name);
                }
            }
        }
    }
}

The code outputs the following: -

Foo is transactionable.
Baz is transactionable.

In this particular example, the mere presence of the TransactionableAttribute will be enough to tell the code that the method decorated with this attribute can belong in a transaction. That's why it's defined with only a bare-bones, parameterless constructor and no other members.

TestClass is then defined with three methods (Foo, Bar,and Baz) where two of them (Foo and Baz) are defined as transactionable. Notice that when attaching an attribute with a constructor that takes no parameters, you do not need to include the open and closed parentheses.

Now for the fun stuff. Let's look more closely at how we can query a class's methods as to the methods' attributes. We start off by using the static Type method GetType to obtain a System.Type object for the TestClass class: -

Type type = Type.GetType("TestClass");

Then we use the Type.GetMethods method to retrieve an array of MethodInfo objects. Each of these objects contains the information about a method in the TestClass class. Using a foreach statement, we iterate through every method: -

foreach(MethodInfo method in type.GetMethods())

Now that we have a MethodInfo object, we can use the MethodInfo.GetCustomAttributes method to retrieve all the user-created attributes for the method. Once again, we use a foreach statement to iterate through the returned array of objects: -

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

At this point in the code, we have an attribute for a method. Now, using the is operator, we query it as to whether it's a TransactionableAttribute attribute. If it is, we print the name of the method: -

if (attr is TransactionableAttribute)
{
Console.WriteLine("{0} is transactionable.",
                     method.Name);
}