In Focus

Reflection In .NET

Reflection in .NET provides functionality to read assemblies from code. In this article, learn how to use Reflection in C# and .NET to read .NET assemblies and their metadata.

Introduction


In this article, I will cover basics of .NET Reflection with examples. I have stated with definition of .NET Reflection and its roadmap. We'll see list of most used classes in the System.Reflection namespace that defines most of the .NET Reflection related functionality. You will also learn how to get the type information using different ways. Use of properties and methods of Type class in .NET Reflection with examples are interesting in this article. You will also see advance Reflection topic like dynamically loading an assembly and late binding in the end of this article.

What is .NET Reflection?


.NET Framework's Reflection API allows you to fetch Type (Assembly) information at runtime or programmatically. We can also implement late binding using .NET Reflection. At runtime, Reflection uses the PE file to read the metadata about an assembly. Reflection enables you to use code that was not available at compile time. .NET Reflection allows application to collect information about itself and also manipulate on itself. It can be used effectively to find all the types in an assembly and/or dynamically invoke methods in an assembly. This includes information about the type, properties, methods and events of an object. With reflection, we can dynamically create an instance of a type, bind the type to an existing object, or get the type from an existing object and invoke its methods or access its fields and properties. We can also access attributes using Reflection. In short, Reflection can be very useful if you don't know much about an assembly.

Using reflection, you can get the kind of information that you will see in the Class Viewer, Object Explorer, or a Class Explorer. You can see all the types in an assembly, their members, their types, and metadata. Here is an example of the Class View in Visual Studio. 
Reflection.gif

Roadmap
 
The System.Reflection namespace and System.Type class play an important role in .NET Reflection. These two works together and allow you to reflect over many other aspects of a type.

Reflection1.gif

System.Reflection Namespace


System.Reflection Namespace contains classes and interfaces that provide a managed view of loaded types, methods, and fields, with the ability to dynamically create and invoke types; this process is known as Reflection in .NET framework. The following table describes some of the commonly used classes:
 
Class Description
Assembly Represents an assembly, which is a reusable, versionable, and self-describing building block of a common language runtime application.
This class contains a number of methods that allow you to load, investigate, and manipulate an assembly.
Module Performs reflection on a module. This class allows you to access a given module within a multifile assembly.
AssemblyName This class allows you to discover numerous details behind an assembly's identity. An assembly's identity consists of the following:
• Simple name.
• Version number.
• Cryptographic key pair.
• Supported culture
EventInfo This class holds information for a given event. Use the EventInfo class to inspect events and to bind to event handlers
FieldInfo This class holds information for a given field.

Fields are variables defined in the class. FieldInfo provides access to the metadata for a field within a class and provides dynamic set and get functionality for the field. The class is not loaded into memory until invoke or get is called on the object.
MemberInfo The MemberInfo class is the abstract base class for classes used to obtain information about all members of a class (constructors, events, fields, methods, and properties).
MethodInfo This class contains information for a given method.
ParameterInfo This class holds information for a given parameter.
PropertyInfo This class holds information for a given property.

Before we start using Reflection, it is also necessary to understand the System.Type class.

In order to continue with all the examples given in this article, I am using Car class as an example, it will look like this:

ICar.cs - Interface
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Text;  
  5.   
  6. namespace Reflection  
  7. {  
  8.     interface ICar  
  9.     {  
  10.         bool IsMoving();  
  11.     }  
  12. }  

Car.cs - Class

  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Text;  
  5.   
  6. namespace Reflection  
  7. {  
  8.     internal class Car  
  9.     {  
  10.         //public variables  
  11.         public string Color;  
  12.   
  13.         //private variables  
  14.         //String licensePlate; // e.g. "Californi 111 222"  
  15.         //double maxSpeed;     // in kilometers per hour  
  16.         //int startMiles; // Stating odometer reading   
  17.         //int endMiles; // Ending odometer reading   
  18.         //double gallons; // Gallons of gas used between the readings   
  19.   
  20.         //private vaiables  
  21.         private int _speed;  
  22.   
  23.         //Speed - read-only property to return the speed  
  24.         public int Speed  
  25.         {  
  26.             get { return _speed; }  
  27.         }  
  28.   
  29.         //Accelerate - add mph to the speed  
  30.         public void Accelerate(int accelerateBy)  
  31.         {  
  32.             //Adjust the speed  
  33.             _speed += accelerateBy;  
  34.         }  
  35.   
  36.         //IsMoving - is the car moving?  
  37.         public bool IsMoving()  
  38.         {  
  39.             //Is the car's speed zero?  
  40.             if (Speed == 0)  
  41.             {  
  42.                 return false;  
  43.             }  
  44.             else  
  45.             {  
  46.                 return true;  
  47.             }  
  48.         }  
  49.   
  50.         //Constructor  
  51.         public Car()  
  52.         {  
  53.             //Set the default values  
  54.             Color = "White";  
  55.             _speed = 0;  
  56.         }  
  57.   
  58.         //Over loaded constructor  
  59.         public Car(string color, int speed)  
  60.         {  
  61.             Color = color;  
  62.             _speed = speed;  
  63.         }  
  64.         //methods  
  65.         public double calculateMPG(int startMiles, int endMiles, double gallons)  
  66.         {  
  67.             return (endMiles - startMiles) / gallons;  
  68.         }    
  69.     }  
  70. }  

SportsCar.cs - Class

  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Text;  
  5.   
  6. namespace Reflection  
  7. {  
  8.     internal class SportsCar : Car  
  9.     {  
  10.         //Constructor  
  11.         public SportsCar()  
  12.         {  
  13.             //Change the default values  
  14.             Color = "Green";  
  15.         }  
  16.     }  
  17. }  

The System.Type Class


The System.Type class is the main class for the .NET Reflection functionality to access metadata. The System.Type class is an abstract class and represents a type in the Common Type System (CLS). It represents type declarations: class types, interface types, array types, value types, enumeration types, type parameters, generic type definitions, and open or closed constructed generic types.
 
The Type class and its members are used to get information about a type declaration and its members such as constructors, methods, fields, properties, and events of a class, as well as the module and the assembly in which the class is deployed.

There are three ways to obtain a Type reference.

Reflection2.gif

Using System.Object.GetType()


This method returns a Type object that represents the type of an object. Obviously, this approach will only work if you have the compile-time knowledge of the type.

ObjectGetTypeDemo.cs
  1. using System;  
  2. namespace Reflection  
  3. {  
  4.     class ObjectGetTypeDemo  
  5.     {  
  6.         static void Main(string[] args)  
  7.         {  
  8.             Car c = new Car();  
  9.             Type t = c.GetType();  
  10.             Console.WriteLine(t.FullName);  
  11.             Console.ReadLine();  
  12.         }  
  13.     }  
  14. }  
Output

Reflection.Car

Using System.Type.GetType()


Another way of getting Type information, which is more flexible is using the GetType() static method of Type class. This method gets the type with the specified name, performing a case-sensitive search.

The Type.GetType() is an overloaded method and accepts the following parameters:
  1. fully qualified string name of the type you are interested in examining
  2. exception should be thrown if the type cannot be found
  3. establishes the case sensitivity of the string
TypeGetTypeDemo.cs

  1. using System;  
  2. namespace Reflection  
  3. {  
  4.     class TypeGetTypeDemo  
  5.     {  
  6.         static void Main(string[] args)  
  7.         {  
  8.             // Obtain type information using the static Type.GetType() method.  
  9.             // (don't throw an exception if Car cannot be found and ignore case).  
  10.             Type t = Type.GetType("Reflection.Car"falsetrue);   
  11.             Console.WriteLine(t.FullName);  
  12.             Console.ReadLine();  
  13.         }  
  14.     }  
  15. }  
Output

Reflection.Car

Using typeof () C# operator


The final way to obtain a type information is using the C# typeof operator. This operator takes the name of the type as a parameter.

TypeofDemo.cs
  1. using System;  
  2. namespace Reflection  
  3. {  
  4.     class TypeofDemo  
  5.     {  
  6.         static void Main(string[] args)  
  7.         {  
  8.             // Get the Type using typeof.  
  9.             Type t = typeof(Car);  
  10.             Console.WriteLine(t.FullName);  
  11.             Console.ReadLine();  
  12.         }  
  13.     }  
  14. }  
Output

Reflection.Car

Type Properties


The System.Type class defines a number of members that can be used to examine a type's metadata. You can split these properties into three categories,
  1. A number of properties retrieve the strings containing various names associated with the class, as shown in the following table:

  2. Property Returns
    Name The name of the data type
    FullName The fully qualified name of the data type (including the namespace name)
    Namespace The name of the namespace in which the data type is defined

  3. It is also possible to retrieve references to further type objects that represent related classes, as shown in the following table:

  4. Property Returns Type Reference Corresponding To
    BaseType Immediate base type of this type
    UnderlyingSystemType The type that this type maps to in the .NET runtime (recall that certain .NET base types actually map to specific predefined types recognized by IL)

  5. A number of Boolean properties indicate whether this type is, for example, a class, an enum, and so on.

  6. Type Meaning in Life
    IsAbstract
    IsArray
    IsClass
    IsCOMObject
    IsEnum
    IsGenericTypeDefinition
    IsGenericParameter
    IsInterface
    IsPrimitive
    IsPublic
    IsNestedPrivate
    IsNestedPublic
    IsSealed
    IsValueType
    IsPointer
    These properties (among others) allow you to discover a number of basic traits about the Type you are referring to (e.g., if it is an abstract method, an array, a nested class, and so forth)
Here is the example of displaying type information using System.Type class properties:

TypePropertiesDemo.cs

  1. using System;  
  2. using System.Text;  
  3. using System.Reflection;   
  4. namespace Reflection  
  5. {  
  6.     class TypePropertiesDemo  
  7.     {  
  8.         static void Main()  
  9.         {  
  10.             // modify this line to retrieve details of any other data type  
  11.             // Get name of type  
  12.             Type t = typeof(Car);  
  13.             GetTypeProperties(t);  
  14.             Console.ReadLine();  
  15.         }  
  16.         public static void GetTypeProperties(Type t)  
  17.         {  
  18.             StringBuilder OutputText = new StringBuilder();  
  19.    
  20.             //properties retrieve the strings   
  21.             OutputText.AppendLine("Analysis of type " + t.Name);  
  22.             OutputText.AppendLine("Type Name: " + t.Name);  
  23.             OutputText.AppendLine("Full Name: " + t.FullName);  
  24.             OutputText.AppendLine("Namespace: " + t.Namespace);  
  25.   
  26.             //properties retrieve references          
  27.             Type tBase = t.BaseType;  
  28.   
  29.             if (tBase != null)  
  30.             {  
  31.                 OutputText.AppendLine("Base Type: " + tBase.Name);  
  32.             }  
  33.              Type tUnderlyingSystem = t.UnderlyingSystemType;  
  34.             if (tUnderlyingSystem != null)  
  35.             {  
  36.                 OutputText.AppendLine("UnderlyingSystem Type: " + tUnderlyingSystem.Name);  
  37.                 //OutputText.AppendLine("UnderlyingSystem Type Assembly: " + tUnderlyingSystem.Assembly);  
  38.             }  
  39.             //properties retrieve boolean          
  40.             OutputText.AppendLine("Is Abstract Class: " + t.IsAbstract);  
  41.             OutputText.AppendLine("Is an Arry: " + t.IsArray);  
  42.             OutputText.AppendLine("Is a Class: " + t.IsClass);  
  43.             OutputText.AppendLine("Is a COM Object : " + t.IsCOMObject);  
  44.   
  45.             OutputText.AppendLine("\nPUBLIC MEMBERS:");  
  46.             MemberInfo[] Members = t.GetMembers();  
  47.   
  48.             foreach (MemberInfo NextMember in Members)  
  49.             {  
  50.                 OutputText.AppendLine(NextMember.DeclaringType + " " +  
  51.                 NextMember.MemberType + "  " + NextMember.Name);  
  52.             }  
  53.             Console.WriteLine(OutputText);  
  54.         }  
  55.     }  
  56. }  
Output

Analysis of type Car
Type Name: Car
Full Name: Reflection.Car
Namespace: Reflection
Base Type: Object
UnderlyingSystem Type: Car
Is Abstract Class: False
Is an Arry: False
Is a Class: True
Is a COM Object : False

PUBLIC MEMBERS:
Reflection.Car Method get_Speed
Reflection.Car Method Accelerate
Reflection.Car Method IsMoving
Reflection.Car Method calculateMPG
System.Object Method ToString
System.Object Method Equals
System.Object Method GetHashCode
System.Object Method GetType
Reflection.Car Constructor .ctor
Reflection.Car Constructor .ctor
Reflection.Car Property Speed
Reflection.Car Field Color

Type Methods


Most of the methods of System.Type are used to obtain details of the members of the corresponding data type - constructors, properties, methods, events, and so on. There is a long list of methods exist, but they all follow the same pattern.
  
Returned Type Methods (The Method with the Plural Name Returns an Array) Description
ConstructorInfo GetConstructor(), GetConstructors() These methods allow you to obtain an array representing the items (interface, method, property, etc.) you are interested in. Each method returns a related array (e.g., GetFields() returns a FieldInfo array, GetMethods() returns a MethodInfo array, etc.). Be aware that each of these methods has a singular form (e.g., GetMethod(), GetProperty(), etc.) that allows you to retrieve a specific item by name, rather than an array of all related items.
EventInfo GetEvent(), GetEvents()
FieldInfo GetField(), GetFields()
InterfaceInfo GetInterface(), GetInterfaces()
MemberInfo GetMember(), GetMembers()
MethodInfo GetMethod(), GetMethods()
PropertyInfo GetProperty(), GetProperties()
  FindMembers() This method returns an array of MemberInfo types based on search criteria.
Type GetType() This static method returns a Type instance given a string name.
  InvokeMember() This method allows late binding to a given item.

For example, two methods retrieve details of the methods of the data type: GetMethod() and GetMethods(). 

  1. Type t = typeof(Car);  
  2. MethodInfo[] methods = t.GetMethods();  
  3. foreach (MethodInfo nextMethod in methods)  
  4. {  
  5.                 // etc.  
  6. }  

Reflecting on Methods


GetMethod() returns a reference to a System.Reflection.MethodInfo object, which contains details of a method. Searches for the public method with the specified name.

GetMethods() returns an array of such references. The difference is that GetMethods() returns details of all the methods, whereas GetMethod() returns details of just one method with a specified parameter list.

Both methods have overloads that take an extra parameter, a BindingFlags enumerated value that indicates which members should be returned - for example, whether to return public members, instance members, static members, and so on.

MethodInfo is derived from the abstract class MethodBase, which inherits MemberInfo. Thus, the properties and methods defined by all three of these classes are available for your use.

Reflection3.gif

For example, the simplest overload of GetMethods() takes no parameters.

GetMethodsDemo.cs
  1. using System;  
  2. using System.Reflection;  
  3.   
  4. namespace Reflection  
  5. {  
  6.     class GetMethodsDemo  
  7.     {  
  8.         static void Main()  
  9.         {  
  10.             // Get name of type  
  11.             Type t = typeof(Car);  
  12.             GetMethod(t);  
  13.             GetMethods(t);  
  14.   
  15.             Console.ReadLine();  
  16.         }  
  17.         // Display method names of type.  
  18.         public static void GetMethods(Type t)  
  19.         {  
  20.             Console.WriteLine("***** Methods *****");  
  21.             MethodInfo[] mi = t.GetMethods();  
  22.             foreach (MethodInfo m in mi)  
  23.                 Console.WriteLine("->{0}", m.Name);  
  24.             Console.WriteLine("");  
  25.         }  
  26.         // Display method name of type.  
  27.         public static void GetMethod(Type t)  
  28.         {  
  29.             Console.WriteLine("***** Method *****");  
  30.             //This searches for name is case-sensitive.   
  31.             //The search includes public static and public instance methods.  
  32.             MethodInfo mi = t.GetMethod("IsMoving");  
  33.             Console.WriteLine("->{0}", mi.Name);  
  34.             Console.WriteLine("");  
  35.         }  
  36.     }  
  37. }  

Output

***** Method *****
->IsMoving

***** Methods *****
->get_Speed
->Accelerate
->IsMoving
->calculateMPG
->ToString
->Equals
->GetHashCode
->GetType

Here, you are simply printing the name of the method using the MethodInfo.Name property. As you might guess, MethodInfo has many additional members that allow you to determine if the method is static, virtual, or abstract. As well, the MethodInfo type allows you to obtain the method's return value and parameter set.

A Second Form of GetMethods( )

A second form of GetMethods( ) lets you specify various flags that filter the methods that are retrieved. It has this general form:

MethodInfo[ ] GetMethods(BindingFlags flags)

This version obtains only those methods that match the criteria that you specify. BindingFlags is an enumeration. Here are several commonly used values:
 
Value Meaning
DeclaredOnly Retrieves only those methods defined by the specified class. Inherited methods are not included.
Instance Retrieves instance methods.
NonPublic Retrieves nonpublic methods.
Public Retrieves public methods.
Static Retrieves static methods.

You can OR together two or more flags. In fact, minimally you must include either Instance or Static with Public or NonPublic. Failure to do so will result in no methods being retrieved.

One of the main uses of the BindingFlags form of GetMethods( ) is to enable you to obtain a list of the methods defined by a class without retrieving the inherited methods. This is especially useful for preventing the methods defined by object from being obtained. For example, try substituting this call to GetMethods( ) into the preceding program:

  1. // Now, only methods declared by MyClass are obtained.  
  2.         MethodInfo[] mi = t.GetMethods(BindingFlags.DeclaredOnly |  
  3.                                 BindingFlags.Instance |BindingFlags.Public);  

Reflecting on Fields and Properties


Behavior of the Type.GetField() and Type.GetFields() is exactly similar to above two methods except Type.GetField() returns to references of System.Reflection.MethodInfo and Type.GetFields() returns to references of System.Reflection.MethodInfo array. Similarly Type.GetProperty() and Type.GetProperties() too.

The logic to display a type's properties is similar:

GetFieldsPropertiesDemo.cs
  1. using System;  
  2. using System.Reflection;  
  3.   
  4. namespace Reflection  
  5. {  
  6.     class GetFieldsPropertiesDemo  
  7.     {  
  8.         static void Main()  
  9.         {  
  10.             // Get name of type  
  11.             Type t = typeof(Car);  
  12.             GetFields(t);  
  13.             GetProperties(t);  
  14.   
  15.             Console.ReadLine();  
  16.         }  
  17.   
  18.         // Display field names of type.  
  19.         public static void GetFields(Type t)  
  20.         {  
  21.             Console.WriteLine("***** Fields *****");  
  22.             FieldInfo[] fi = t.GetFields();  
  23.             foreach (FieldInfo field in fi)  
  24.                 Console.WriteLine("->{0}", field.Name);  
  25.             Console.WriteLine("");  
  26.         }  
  27.         // Display property names of type.  
  28.         public static void GetProperties(Type t)  
  29.         {  
  30.             Console.WriteLine("***** Properties *****");  
  31.             PropertyInfo[] pi = t.GetProperties();  
  32.             foreach (PropertyInfo prop in pi)  
  33.                 Console.WriteLine("->{0}", prop.Name);  
  34.             Console.WriteLine("");  
  35.         }  
  36.     }  
  37. }  

Output

***** Fields *****
->Color

***** Properties *****
->Speed

Reflecting on Implemented Interfaces


GetInterfaces() returns an array of System.Types. his should make sense given that interfaces are, indeed, types:

GetInterfacesDemo.cs
  1. using System;  
  2. using System.Reflection;  
  3.   
  4. namespace Reflection  
  5. {  
  6.     class GetInterfacesDemo  
  7.     {  
  8.         static void Main()  
  9.         {  
  10.             // Get name of type  
  11.             Type t = typeof(Car);  
  12.             GetInterfaces(t);  
  13.   
  14.             Console.ReadLine();  
  15.         }  
  16.         // Display implemented interfaces.  
  17.         public static void GetInterfaces(Type t)  
  18.         {  
  19.             Console.WriteLine("***** Interfaces *****");  
  20.             Type[] ifaces = t.GetInterfaces();  
  21.             foreach (Type i in ifaces)  
  22.                 Console.WriteLine("->{0}", i.Name);  
  23.         }  
  24.     }  
  25. }  

***** Interfaces *****
->ICar

Reflecting on Method Parameters and Return Values


To play with method parameters and their return types, we first need to build MethodInfo[] array using GetMethods() function. The MethodInfo type provides the ReturnType property and GetParameters() method for these very tasks. 
  1. using System;  
  2. using System.Reflection;  
  3. using System.Text;  
  4.   
  5. namespace Reflection  
  6. {  
  7.     class GetParameterInfoDemo  
  8.     {  
  9.         static void Main()  
  10.         {  
  11.             // Get name of type  
  12.             Type t = typeof(Car);  
  13.             GetParametersInfo(t);  
  14.   
  15.             Console.ReadLine();  
  16.         }  
  17.         //Display Method return Type and paralmeters list  
  18.         public static void GetParametersInfo(Type t)  
  19.         {  
  20.             Console.WriteLine("***** GetParametersInfo *****");  
  21.             MethodInfo[] mi = t.GetMethods();  
  22.             foreach (MethodInfo m in mi)  
  23.             {  
  24.                 // Get return value.  
  25.                 string retVal = m.ReturnType.FullName;  
  26.                 StringBuilder paramInfo = new StringBuilder();  
  27.                 paramInfo.Append("(");  
  28.   
  29.                 // Get params.  
  30.                 foreach (ParameterInfo pi in m.GetParameters())  
  31.                 {  
  32.                     paramInfo.Append(string.Format("{0} {1} ", pi.ParameterType, pi.Name));  
  33.                 }  
  34.                 paramInfo.Append(")");  
  35.   
  36.                 // Now display the basic method sig.  
  37.                 Console.WriteLine("->{0} {1} {2}", retVal, m.Name, paramInfo);  
  38.             }  
  39.             Console.WriteLine("");  
  40.         }  
  41.     }  
  42. }  

Output

***** GetParametersInfo *****
->System.Int32 get_Speed ()
->System.Void Accelerate (System.Int32 accelerateBy )
->System.Boolean IsMoving ()
->System.Double calculateMPG (System.Int32 startMiles System.Int32 endMiles Syst
em.Double gallons )
->System.String ToString ()
->System.Boolean Equals (System.Object obj )
->System.Int32 GetHashCode ()
->System.Type GetType ()

Reflecting on Constructor


GetConstractors() function returns an array of ConstractorInfo elements, which we can use to get constructors' information.

GetConstractorInfoDemo.cs
  1. using System;  
  2. using System.Reflection;  
  3. namespace Reflection  
  4. {  
  5.     class GetConstractorInfoDemo  
  6.     {  
  7.         static void Main()  
  8.         {  
  9.             // Get name of type  
  10.             Type t = typeof(Car);  
  11.             GetConstructorsInfo(t);  
  12.   
  13.             Console.ReadLine();  
  14.         }  
  15.         // Display method names of type.  
  16.         public static void GetConstructorsInfo(Type t)  
  17.         {  
  18.             Console.WriteLine("***** ConstructorsInfo *****");  
  19.             ConstructorInfo[] ci = t.GetConstructors ();  
  20.             foreach (ConstructorInfo  c in ci)  
  21.                 Console.WriteLine(c.ToString () );  
  22.             Console.WriteLine("");  
  23.         }  
  24.     }  
  25. }  

Output

***** ConstructorsInfo *****
Void .ctor()
Void .ctor(System.String, Int32)

Assembly Class


System.Reflection namespace provide a class called Assembly. We can use this Assembly class to fetch the information about the assembly and manipulate it; this class allows us to load modules and assemblies at run time. Assembly class contacts with PE file to fetch the metadata information about the assembly at runtime. Once we load an assembly using this Assembly class, we can search the type information within the assembly. It is also possible to create instance of types return by the Assembly class

Dynamically loading an Assembly


Assembly Class provides following methods to load an assembly at runtime,
  1. Load ()
    This static overloaded method takes the assembly name as input parameter and searched the given assembly name in the system.

  2. LoadFrom ()
    This static overloaded method take complete path of the an assembly, it will directly look into that particular location instead of searching in the system.

  3. GetExecutingAssembly ()
    Assembly class also provide another method to obtain the currently running assembly information using GetExecutingAssembly() methods. This method is not overloaded one.

  4. GetTypes()
    Assembly class also provide a nice feature called GetTypes Method which allows you to obtain details of all the types that are defined in the corresponding assembly.

  5. GetCustomAttributes()
    This static overloaded method gets the attributes attached to the assembly. You can also call GetCustomAttributes() specifying a second parameter, which is a Type object that indicates the attribute class in which you are interested.
AssemblyDemo.cs

  1. class AssemblyDemo  
  2. {  
  3.     static void Main()  
  4.     {  
  5.         Assembly objAssembly;  
  6.         // You must supply a valid fully qualified assembly name here.              
  7.         objAssembly = Assembly.Load("mscorlib,2.0.0.0,Neutral,b77a5c561934e089");  
  8.         // Loads an assembly using its file name     
  9.         //objAssembly = Assembly.LoadFrom(@"C:\Windows\Microsoft.NET\Framework\v1.1.4322\caspol.exe");   
  10.         //this loads currnly running process assembly  
  11.         // objAssembly = Assembly.GetExecutingAssembly();  
  12.   
  13.         Type[] Types = objAssembly.GetTypes();  
  14.         // Display all the types contained in the specified assembly.  
  15.         foreach (Type objType in Types)  
  16.         {  
  17.             Console.WriteLine(objType.Name.ToString());  
  18.         }  
  19.   
  20.         //fetching custom attributes within an assembly  
  21.         Attribute[] arrayAttributes =  
  22.          Attribute.GetCustomAttributes(objAssembly);  
  23.         // assembly1 is an Assembly object  
  24.   
  25.         foreach (Attribute attrib in arrayAttributes)  
  26.         {  
  27.             Console.WriteLine(attrib.TypeId);  
  28.         }  
  29.   
  30.         Console.ReadLine();  
  31.     }  
  32. }
Reflection4.gif

Late Binding


Late binding is the powerful tool in .NET Reflection, which allows you to create an instance of a given type and invoke its members at runtime without having compile-time knowledge of its existence; this technique is also called dynamic invocation. This technique is useful when working with objects that are does not provide details at compile time. In this technique, developers are responsible for passing the correct signature of methods before invoking them, otherwise it will throw an error. It is very important to take the right decision when using this approach. Use of late binding may also impact the performance of your application.

LateBindingDemo.cs
  1. using System;  
  2. using System.Reflection;  
  3.   
  4. namespace Reflection  
  5. {  
  6.     class LateBindingDemo  
  7.     {  
  8.         static void Main()  
  9.         {  
  10.             Assembly objAssembly;  
  11.             // Loads an assembly    
  12.             objAssembly = Assembly.GetExecutingAssembly();  
  13.   
  14.             //get the class type information in which late bindig applied  
  15.             Type classType = objAssembly.GetType("Reflection.Car");  
  16.   
  17.             //create the instance of class using System.Activator class  
  18.             object obj = Activator.CreateInstance(classType);  
  19.   
  20.             //get the method information  
  21.             MethodInfo mi = classType.GetMethod("IsMoving");  
  22.   
  23.             //Late Binding using Invoke method without parameters  
  24.             bool isCarMoving;  
  25.             isCarMoving = (bool)mi.Invoke(obj, null);  
  26.             if (isCarMoving)  
  27.             {  
  28.                 Console.WriteLine("Car Moving Status is : Moving");  
  29.             }  
  30.             else  
  31.             {  
  32.                 Console.WriteLine("Car Moving Status is : Not Moving");  
  33.             }  
  34.   
  35.             //Late Binding with parameters  
  36.             object[] parameters = new object[3];  
  37.             parameters[0] = 32456;//parameter 1 startMiles  
  38.             parameters[1] = 32810;//parameter 2 end Miles  
  39.             parameters[2] = 10.6;//parameter 3 gallons  
  40.             mi = classType.GetMethod("calculateMPG");  
  41.             double MilesPerGallon;  
  42.             MilesPerGallon = (double)mi.Invoke(obj, parameters);  
  43.             Console.WriteLine("Miles per gallon is : " + MilesPerGallon);  
  44.   
  45.             Console.ReadLine();  
  46.         }  
  47.   
  48.     }  
  49. }  

Output

Car Moving Status is : Not Moving
Miles per gallon is : 33.3962264150943

Reflection Emit


Reflection emit supports the dynamic creation of new types at runtime. You can define an assembly to run dynamically or to save itself to disk, and you can define modules and new types with methods that you can then invoke.

Conclusion


Reflection in .NET is a big topic. In this article, I tried to covers most of the important functionality related to .NET reflection. 

Thanks for reading my article; I hope you enjoyed it.