Reflection and Attributes in C#

Attributes are attached to program entities such as types and methods to provide information about the entity at runtime using reflection. An example of attribute usage is the help context menu that Visual Studio provides for the methods and types. We can declare an attribute class like an ordinary class but it needs to be derived from System. Attribute and need to mark it with the AttributeUsage attribute. AttributeUsage attribute defines the program entities to which the attribute can be applied.

Attribute classes have two types of parameters.

  1. Named Parameters
  2. Positional Parameters

We can use reflection to discover information about a program entity at runtime and to create an instance of a type at runtime. Most of the classes and interfaces needed for reflection are defined in the System. Reflection namespace.

System. Type is the most fundamental to working with reflection functionality in .NET and it represents a type in the CTS. There are several ways to obtain the Type object.

Type Object

Once we have an instance of the type we can get the information about the type using several methods like GetMembers() or GetMethods(). Following are the methods defined in the Type class.

Following are the main classes defined in the System. Reflection namespace.

Assembly Represents an assembly
EventInfo This class holds information for a given event.
FieldInfo This class holds information for a given field.
MemberInfo Class is the abstract base class for classes used to obtain information about all members of a class.
MethodInfo This class contains information for a given method.
ConstructorInfo This class contains information for a given constructor.

In the following example, we query the type for the member fields and methods of the type and dynamically invoke the member method.

class Test {
    public int a;

    public void Hello() {
        Console.WriteLine("Hello.....");
    }
}

class Program {
    static void Main(string[] args) {
        Type typeObj = typeof(Test);
        foreach (MethodInfo mi in typeObj.GetMethods()) {
            Console.WriteLine("Following are the methods in Test class");
            Console.WriteLine("Method {0}", mi.Name);
        }

        foreach (FieldInfo fi in typeObj.GetFields()) {
            Console.WriteLine("Following are the fields in Test class");
            Console.WriteLine("Field {0}", fi.Name);
        }

        object o = Activator.CreateInstance(typeObj);

        MethodInfo method = typeObj.GetMethod("Hello");
        Console.Write("\t");
        method.Invoke(o, null);

        Console.ReadLine();
    }
}