Reflection In C# With Examples

In C#, reflection is a process to get metadata of types, modules, assemblies, etc. at runtime.
You can use reflection to create an instance of a type dynamically, bind the type to an existing object, retrieve the type from an existing object, and invoke its methods, fields, and properties.

Metadata contains information about the methods, properties, variables, etc. declared inside of an assembly.

The System.Reflection namespace contains classes that allow you to achieve reflection. So, make sure to add using System; and using System.Reflection; at the top of your .cs file.

Reflection In C#
Reflection in C#

System.Reflection Namespace

Some of the most commonly used reflection namespace classes are:

  • Assembly: This class allows us to load, investigate and manipulate an assembly dynamically.
  • Module: Module class in reflection is used to discover information, such as the assembly containing the module and the classes in the module. You can also retrieve a list of all global methods and non-global methods specified in the module.
  • MethodInfo: This class is used to hold data about a method, such as its name, return type, parameters, access modifiers, and so on. To invoke a specific method, use the Type’s GetMethods() or GetMethod() method.
  • PropertyInfo: This class in reflection is used to contain information such as the name and data type of the property, and to get or set the value of the property.
  • FieldInfo: This class allows you to access field info. It is used to retrieve or update field values as well as discover information such as field names, access modifiers (such as public or private), and implementation details.
  • EventInfo: This class holds information such as the name, event-handler data type, custom attributes, etc. for a given event. Use this class to inspect events and bind to event handlers.
  • ConstructorInfo: This class is used to discover information such as the name, parameters, access modifiers, and implementation details of a constructor. Use the GetConstructors() or GetConstructor() method of Type to call a specific constructor.
  • CustomAttributeData: This class is used to get information on custom attributes or to examine attributes without having to create instances of them.

Reflection Example 1:

In the below code snippet, The typeof method is used to load the type t as an int. Then we use reflection on t to find information about the int type, such as its Name, FullName, Namespace, and BaseType.

// C# program to demonstrate the use of Reflection
using System;
using System.Reflection;
namespace Reflection_Example
{
    class Program
    {     
        static void Main(string[] args)
        {
            // Initialize t as typeof int
            Type t = typeof(int);

            // Use Reflection to retrieve the information related to type t
            Console.WriteLine($" Name : {t.Name}");
            Console.WriteLine($" Full Name : { t.FullName}");
            Console.WriteLine($" Namespace : {t.Namespace}");
            Console.WriteLine($" Base Type : {t.BaseType}");
            Console.ReadLine();
        }
    }
}

Following is the output of the above program.

reflection example in CSharp

Example 2:

static void Main(string[] args)
        {
            // Using Reflection to get information of an Assembly:
            Assembly info = typeof(int).Assembly;
            Console.WriteLine(info);
            Console.ReadLine();

            // Output:
            // mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
        }

When to use Reflection in C#?

Reflection can be useful in the following scenarios:

  • Reflection in C# can be used to implement late binding and dynamically access methods, fields, and properties of a type in an assembly.
  • We use reflection to find assembly information at run time. It can be used to perform data binding.
  • Reflection in C# can be used for instantiating types in an assembly at the runtime by using the ‘Activator.CreateInstance‘ method.
  • If you want information about attributes on a type or method, you can use reflection.
  • Reflection can be used to create a shared assembly.
  • Reflection can be used to solve the DLL hell problem by creating shared assemblies.
  • Reflection eases the process of deployment as we can do versioning of an assembly using reflection (Example: [assembly: AssemblyVersion(“1.0.0.0”)]).
  • It can be also used to access the private data members of a class.

Dynamic Assembly Loading Using Reflection In C#

Let’s write a C# program to create a private assembly and load that assembly at runtime by using reflection.

Write the following program in notepad or Visual Studio editor and save the file as ‘User.cs’ in the local folder( Example D:\User\User.cs).

using System;
namespace Reflection
{
    // Class
    public class User
    {
        // field
        public int userId = 52894;

        //Method
        public string GetName()
        {
            return "Mr. Shekh Ali";
        }

        //Method
        public string Print(string message)
        {
            return message;
        }
    }
}

Open Visual Studio command prompt and execute the following command.
csc /t:library User.cs

Command to generate assembly using reflection in C#
Command to generate a private assembly.

A new assembly ‘User.dll’ is created in the ‘D:/User/’ drive.

Create Private Assembly Using Reflection in c#
A private assembly is created after executing the above command.

Now create a new console application, and write the following program to load the assembly at the runtime using the reflection.

Example 3:

Retrieving metadata of any assembly at runtime

In the following example, the MethodInfo and FieldInfo objects of the System.Reflection class must be initialized to discover the attributes of the method and field associated with the class.

//    Load the assembly at runtime using reflection in C#. 
using System;
using System.Reflection;
namespace Reflection
{
    class Program
    {
        static void Main(string[] args)
        {
         // Dynamically load assembly from file User.dll
          Assembly assembly = Assembly.LoadFile(@"D:\User\User.dll");

         // Get type of class 'User' from the loaded assembly  
          Type type = assembly.GetType("Reflection.User");

         // Create instance of 'User' class
          object instance = Activator.CreateInstance(type);

         // Call method: public string GetName()
          MethodInfo method = type.GetMethod("GetName");

        // Invoke method: 
           string name = Convert.ToString(method.Invoke(instance, null));
         //Call public field
          FieldInfo field = type.GetField("userId");
          int userId = (int)field.GetValue(instance);

          Console.WriteLine(userId);
          Console.WriteLine(name);         
          Console.ReadLine();

        }
    }
}


image Output of Reflection program
The output of the above program.

In the above program, we are calling field and method data from the assembly at runtime.

Access private method using reflection in C#

In C#, calling private methods from one class to another is technically impossible.
However, using reflection can call private methods from one class to another. Below is a C# program where we created a user class with private methods.
Here, we will try to call the private method of the User class to the Main () method of the Program class.

Example 4:

// Invoking the private method using reflection
using System;
using System.Reflection;
namespace Reflection
{
    class User
    {
        // private method
        private string PrivateMethod()
        {
            return "Private method executed !!";
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
          // Create object of User class
           User instance = new User();
         // Get type of User class 
          Type type = typeof(User);

         // Call private method with required binding constraints. 
          MethodInfo method = type.GetMethod("PrivateMethod", BindingFlags.NonPublic | BindingFlags.Instance);

        // Invoke method at the runtime 
           string name = Convert.ToString(method.Invoke(instance, null));
        
          Console.WriteLine(name);         
          Console.ReadLine();
        }
        //Output: Private method executed !!
    }
}
Calling private method using Reflection in c#
The output of the above C# program

In the example above, we used reflection to access the private methods of the class. Reflection in C # is often used in user interface applications such as ASP.NET. We can directly set the properties of TextBox, Button, ComboBox, and other controls.

To read more about reflection, please visit this MSDN link.

Conclusion:

In this post, I tried to cover most of the important functionality related to .NET reflection. I hope you found this post useful about Reflection. If so, please share it with others. Your suggestions, comments, and constructive criticism are greatly appreciated.

FAQ

Q: Is using reflection in C# a good practice?

Ans: It is generally not recommended to use reflection in application code because it eliminates strict type-checking.

Q: What is reflection used for in C#?

Ans: Reflection provides metadata at runtime that describes assemblies, modules, and types. You can use reflection to create an instance of a type dynamically and to invoke its methods, fields, and properties.

Q: How to load an assembly at runtime using reflection in C#?

Ans: The Assembly.LoadFile() method is used to load an assembly at runtime.

Recommended Articles

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments