Reflection is used to get the type information at runtime. In reflection, we retrieve the type instance which describes the assemblies, types, and modules. Using reflection we can get the information about an existing type and can also invoke its methods and access its properties. The following code gets the type instance for an integer variable.
- int i=1;
- Type type = i.GetType();
We can get the type information for the integer type using this type instance. For example, if we want the assembly information for the integer type then we can use the following code:
- Console.WriteLine(type.Assembly);
We get the following output for the statement above. As we can see, we get all the details for the containing assembly of the type.
We use attributes to associate metadata with a class. We are not restricted to using only the built-in attributes. We can create our own custom attributes if required. We define a custom attribute as a class deriving from the Attribute class.
When we define custom attributes in the source code we should be able to access that information at runtime. We can use reflection to access the information defined using custom attributes. In the following code, we are first defining a custom attribute called Employee and then attaching it to a class.
- [System.AttributeUsage(System.AttributeTargets.Class,AllowMultiple = true)]
- public class Employee : System.Attribute
- {
- string name;
- public Employee(string name)
- {
- this.name = name;
- }
- public string GetName()
- {
- return name;
- }
- }
- [Employee("Ashish Shukla")]
- public class TestClass
- {
- }
We have created a class deriving from the attribute class and applied it to the TestClass. Once we have applied the attribute to the TestClass class we can access it in the code as:
- TestClass obj = new TestClass();
- Type type = obj.GetType();
- System.Attribute[] attrs = System.Attribute.GetCustomAttributes(type);
- foreach (System.Attribute attr in attrs)
- {
- if (attr is Employee)
- {
- Employee a = (Employee)attr;
- System.Console.WriteLine("{0}", a.GetName());
- }
- }
In the code above we have done the following:
- Declared an instance of Type class
- Assigned to the Type class instance the return value of GetType()
- Calling the GetCustomAttributes() method of the Attribute class that returns an array of Attribute class containing custom attributes.
- Once we have custom attributes we can iterate over the attributes and fetch the information associated with the attribute.
So using the custom attributes, we can attach the information to the class and access it during runtime. We have hardcoded the name "Ashish" in the sample above but this information need not be hardcoded. It can come from the database or any other source.
Suppose the employee name is Ashish, then we can write conditional logic based on the name of the employee.
- if (a.GetName().ToLower() == "ashish")
- {
- }
In the code above we are checking if the attribute attached to the class has the value ashish and if it is ashish then we can implement some conditional logic.
So using custom attributes is a powerful way to attach metadata to a class and access it during runtime.