Reflection in C#

In this article, we will discuss Reflection in C#, with the help of coding examples we will see how to implement Reflection in C#. Objects (of type Type) are provided through reflection in C# to describe assemblies, modules, and types. Reflection can be used to dynamically generate an instance of a type, bind a type to an existing object, or retrieve a type from an existing object so you can access its fields and attributes and call its methods. We will discuss reflection in C# and how to implement it in this tutorial. A reflection is a potent tool in C# that allows you to examine and alter the behavior of types, objects, and assemblies in real time. Reflection offers a technique for learning about types and the individuals that make them up as well as for dynamically invoking object fields, attributes, and methods.



How to use Reflection in C#:


With the help of C# Reflection, the program can act independently and obtain information. It dynamically invokes assembly methods and efficiently finds all varieties of assemblies. The major important class which is used in reflection is System. Type class is an abstract class representing a type called CTS (Common Type System). With the help of this class, we can locate the types we used in namespace modules and confirm if a given type is a value type or a reference type.

C# provides System.Reflection namespace using which we can perform reflection. The System. Reflection namespace contains the classes:


  • Type


  • MemberInfo


  • ContructorInfo


  • FieldInfo


  • MethodInfo



Here are some examples of how to use reflection in C#:

C# Type Class:


The Type class is the main method for gaining access to the metadata. This class contains methods and attributes via which we can retrieve information about a type declaration. For example:

Get the type of object:



using System;

namespace ReflectionDemo

{

    internal class Program

    {

        static void Main(string[] args)

        {

           

            String studentName = "David";

            // get the current type of studentName

            Type studentNameType = studentName.GetType();

            Console.WriteLine("Type is: " + studentNameType);

        }

    }

}




Output:


 Type
is: System.String




C# Reflection TypeInfo:


Class types, interface types, array types, value types, enumeration types, type parameters, generic type definitions, and open or closed-built generic types are all represented by type classes.

Given below is an example of TypeInfo:

As you can see we have a class.


public class Student

{

    public string FullName { get; set; }

    public int Class { get; set; }

    public DateTimeDateOfBirth { get; set; }

    public string GetCharacteristics()

    {

  return "";

    }

}



And we want to get all methods and properties declared within this type. Using TypeInfo we can do this easily and with cleanness:


TypeInfostudentInfo = typeof(Student).GetTypeInfo();

IEnumerable<PropertyInfo>declaredProperties = studentInfo.DeclaredProperties;

IEnumerable<MethodInfo>declaredMethods = studentInfo.DeclaredMethods;





C# Reflection to get Assembly:


The Type class provides a property called Assembly which generates the Assembly of the code. For example:



using System;

namespace ReflectionDemo

{

    internal class Program

    {

        static void Main(string[] args)

        {

            // get typeof the Program class and load it to Type variable t    

            Type t = typeof(Program);

            // get Assembly of variable t using the Assembly property

            Console.WriteLine(t.Assembly);

        }

    }

}




Output:


ReflectionDemo
, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null


In the above code example. Look at the code.



// get type of Program and load it to Type variable t    

            Type t = typeof(Program);


Here, we have used the type of operator that returns the type of the Program class and assigned it to Type variable t.


C# Reflection with String:



using System;

namespace ReflectionDemo

{

    internal class Program

    {

        static void Main(string[] args)

        {

            // Initialise t as typeof string

            Type t = typeof(string);

            // Use Reflection to find about

            // any sort of data related to t

            Console.WriteLine("Name : {0}", t.Name);

            Console.WriteLine("Full Name : {0}", t.FullName);

            Console.WriteLine("Namespace : {0}", t.Namespace);

            Console.WriteLine("Base Type : {0}", t.BaseType);

        }

    }

}




Output:


 Name
: String


 Full
Name : System.String


 Namespace
: System


 Base
Type : System.Object




Create an Instance of a type:



 Type
type = typeof(SomeClass);


 object
obj = Activator.CreateInstance(type)





C# MemberInfo class:


The MemberInfo class offers access to member metadata and gathers data about a member's attributes. This class used to gather data on every member of a class is called MemberInfo, and it is its abstract base class (constructors, events, fields, methods, and properties). This class introduces the fundamental features that each member offers.

For getting the list of all members within Type we can use the GetMembers method:



 System.Reflection.MemberInfo[] mbrInfoArray = type.GetMembers();




Given below is an example of MemberInfo class:

Example:


using System;

namespace ReflectionDemo

{

    internal class Program

    {

        static void Main(string[] args)

        {

            Type theType = Type.GetType("System.Reflection.Assembly");

            Console.WriteLine("\nSingle Type is {0}\n", theType);

            MemberInfo[] mbrInfoArray = theType.GetMembers();

            foreach (MemberInfo mbrInfo in mbrInfoArray)

            {

                Console.WriteLine("{0}  {1}", mbrInfo.MemberType, mbrInfo.Name);

            }

        }

    }

}




Output:

Single Type is System.Reflection.Assembly

Method  Load

Method  LoadWithPartialName

Method  Load

Method  GetExecutingAssembly

Method  GetCallingAssembly

Method  GetEntryAssembly

Method  get_DefinedTypes

Method  GetTypes

Method  get_ExportedTypes

Method  GetExportedTypes

Method  GetForwardedTypes

Method  get_CodeBase

Method  get_EntryPoint

Method  get_FullName

Method  get_ImageRuntimeVersion

Method  get_IsDynamic

Method  get_Location

Method  get_ReflectionOnly

Method  get_IsCollectible

Method  GetManifestResourceInfo

Method  GetManifestResourceNames

Method  GetManifestResourceStream

Method  GetManifestResourceStream

Method  get_IsFullyTrusted

Method  GetName

Method  GetName

Method  GetType

Method  GetType

Method  GetType

Method  IsDefined

Method  get_CustomAttributes

Method  GetCustomAttributesData

Method  GetCustomAttributes

Method  GetCustomAttributes

Method  get_EscapedCodeBase

Method  CreateInstance

Method  CreateInstance

Method  CreateInstance

Method  add_ModuleResolve

Method  remove_ModuleResolve

Method  get_ManifestModule

Method  GetModule

Method  GetModules

Method  GetModules

Method  get_Modules

Method  GetLoadedModules

Method  GetLoadedModules

Method  GetReferencedAssemblies

Method  GetSatelliteAssembly

Method  GetSatelliteAssembly

Method  GetFile

Method  GetFiles

Method  GetFiles

Method  GetObjectData

Method  ToString

Method  get_GlobalAssemblyCache

Method  get_HostContext

Method  Equals

Method  GetHashCode

Method  op_Equality

Method  op_Inequality

Method  CreateQualifiedName

Method  GetAssembly

Method  Load

Method  Load

Method  LoadFile

Method  LoadFrom

Method  LoadFrom

Method  UnsafeLoadFrom

Method  LoadModule

Method  LoadModule

Method  ReflectionOnlyLoad

Method  ReflectionOnlyLoad

Method  ReflectionOnlyLoadFrom

Method  get_SecurityRuleSet

Method  GetType

Property        DefinedTypes

Property        ExportedTypes

Property        CodeBase

Property        EntryPoint

Property        FullName

Property        ImageRuntimeVersion

Property        IsDynamic

Property        Location

Property        ReflectionOnly

Property        IsCollectible

Property        IsFullyTrusted

Property        CustomAttributes

Property        EscapedCodeBase

Property        ManifestModule

Property        Modules

Property        GlobalAssemblyCache

Property        HostContext

Property        SecurityRuleSet

Event   ModuleResolve




C# ConstructorInfo Method:


To obtain information about constructors, utilize the array of ConstructorInfo components returned by the GetConstructors() function.

Type.GetMember() Method is used to get the specified members of the current Type.

Given below is an example of the ConstructorInfo method.

Example:


using System;

namespace ReflectionDemo

{

    internal class Program

    {

        static void Main(string[] args)

        {

            // Display method names of type.  

        public static void GetConstructorsInfo(Type t)

        {

            Console.WriteLine("----- ConstructorsInfo output-----");

            ConstructorInfo[] ci = t.GetConstructors();

            foreach (ConstructorInfo c in ci)

                Console.WriteLine(c.ToString());

            Console.WriteLine("");

        }

        }

    }

}




Output:


----- ConstructorsInfo output-----

Void .ctor(Char[])

Void .ctor(Char[], Int32, Int32)

Void .ctor(Char*)

Void .ctor(Char*, Int32, Int32)

Void .ctor(SByte*)

Void .ctor(SByte*, Int32, Int32)

Void .ctor(SByte*, Int32, Int32, System.Text.Encoding)

Void .ctor(Char, Int32)

Void .ctor(System.ReadOnlySpan`1[System.Char])




As you can see members can have different types:


• Constructor Specifies that the member is a constructor, representing a ConstructorInfo member.


•  Custom Specifies that the member is a custom member type.


• Event Specifies that a member is an event, representing an EventInfo member.


• Field Specifies that the member is a field, representing a FieldInfo member.


• Method Specifies that the member is a method, representing a MethodInfo member.


•  NestedType Specifies that the member is a nested type, extending MemberInfo.


•  Property Specifies that the member is a property, representing a PropertyInfo member.


• TypeInfo Specifies that the member is a type, representing a TypeInfo member.



C# FieldInfo class:


FieldInfo class discovers the attributes of a field and provides access to field metadata.

To get a list of public fields in an object, we'll use Type's GetFields method:



Type myObjectType = typeof(MyObject);

System.Reflection.FieldInfo[] fieldInfo = myObjectType.GetFields();



There is plenty of helpful information in the FieldInfo class that is returned. The true power comes from the fact that it also can set that field on an instance of an object.



using System;

namespace ReflectionDemo

{

   

      class MyClass

        {

            public string myString;

            public MyClass myInstance;

            public int myInt;

        }

    public class Program

    {

        static void Main(string[] args)

        {

        Type myType = typeof(MyClass);

    System.Reflection.FieldInfo[] fieldInfo = myType.GetFields();

   

    MyClass myClass = new MyClass();

    foreach (System.Reflection.FieldInfo info in fieldInfo)

    {

       switch (info.Name)

       {

        case "myString":

         info.SetValue(myClass, "string value");

         break;

        case "myInt":

         info.SetValue(myClass, 42);

         break;

        case "myInstance":

         info.SetValue(myClass, myClass);

         break;

       }

    }

   

    //read back the field information

    foreach (System.Reflection.FieldInfo info in fieldInfo)

    {

       Console.WriteLine(info.Name + ": " +

        info.GetValue(myClass).ToString());

    }

        }

    }

}





Output:


 myString
: string value


 myInstance
: MyClass


 myInt
: 42





C# Propertyinfo class:


The PropertyInfo class identifies a property's characteristics and gives users access to property metadata.

The FieldInfo class and the PropertyInfo class are quite similar and both allow you to set the value of a property on an instance. The GetAccessors method also enables you to obtain the get and set accessors as separate MethodInfo classes.




Type myClassType = typeof(MyClass);

//Get public properties

System.Reflection.PropertyInfo[] propertyInfos = myClassType.GetProperties();



System.Reflection.MethodInfo[] accessorMethodInfos = propertyInfo.GetAccessors();




Get the properties  of a type:



 Type
type = typeof(SomeClass);


 PropertyInfo
[] properties = type.GetProperties();


 foreach
(PropertyInfo property in properties)


 {


 Console.WriteLine(property.Name);


 }




Given below is an example of PropertyInfo class.

Example:


using System;

namespace ReflectionDemo

{

   

      class MyClass

        {

            public string myString;

            public MyClass myInstance;

            public int myInt;

        }

    public class Program

    {

        static void Main(string[] args)

        {

    var type = typeof(University.Student);

   

    var propertyInfos = type.GetProperties();

   

    foreach(var propertyInfo in propertyInfos)

    {

      Console.Write(propertyInfo.Name+" { ");

      var accessors = propertyInfo.GetAccessors();

      foreach(var accessor in accessors)

      {

        Console.Write(accessor.Name+"; ");

      }

      Console.WriteLine("}");

    }

        }

    }

 

  public class Student

  {

    public string FullName { get; set; }

   

    public int Class { get; set; }

   

    public DateTime DateOfBirth { get{ return _dateOfBirth; } }

   

    private DateTime _dateOfBirth = DateTime.MinValue;

   

    public string GetCharacteristics()

    {

      return "";

    }

  }

  namespace Department {

   

    public class Professor {

     

        public string FullName { get; set; }

     

    }

  }

}




Output:

 

FullName { get_FullName; set_FullName; }

 Class { get_Class; set_Class; }

 DateOfBirth { get_DateOfBirth; }





C# MethodInfo class:


The MethodInfo class identifies a method's characteristics and gives users access to method metadata.

By default, the GetMethods function on the Type class returns all of a type's public instance methods. Here, all of the public MyClass class methods are represented as an array of MethodInfo instances.


 System.Reflection.MethodInfo[] methodInfos = myClassType.GetMethods();

 //or

 System.Reflection.MethodInfo[] methodInfos = myClassType.GetTypeInfo().DeclaredMethods;



Invoke a method of an abject:



 object
obj = new SomeClass();


 Type
type = obj.GetType();


 MethodInfo
method = type.GetMethod("SomeMethod");


 method
.Invoke(obj, null);




Given below is an example of invoking a methodInfo class implementation.

Example:


using System;

namespace ReflectionDemo

{

    public class Program

    {

      public void Method1()

      {

          Console.WriteLine("Method invoked!");

      }

      public void Method2()

      {

          Console.WriteLine("Method invoked!");

      }

      public void Method3()

      {

          Console.WriteLine("Method invoked!");

      }

        static void Main(string[] args)

        {

          var instance = new Program();

          //using BindingFlags get all non-static, public methods that are declared in type Program

          MethodInfo[] methods = typeof(Program).GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly);

          foreach (MethodInfo info in methods)

          {

              Console.Write(info.Name + " : ");

              info.Invoke(instance, null);

          }

        }

    }

}




Output:


 Method1
: Method invoked!


 Method2
: Method invoked!


 Method3
: Method invoked!





Conclusion:


C# Reflection covers the important functionalities in .Net here; we have learned how Reflection works in C#.Net with several examples. Reflection is used to locate every type in an assembly and/or dynamically call assembly methods. This comprises details about an object's type, attributes, methods, and events. With the use of reflection, we can dynamically generate an instance of a type, bind a type to an existing object, or extract a type from an existing object to access its fields and properties and call its methods.

Hope you enjoyed reading this article and found it useful. Please share your thoughts and recommendations in the comment section below.



Share This Post

Linkedin
Fb Share
Twitter Share
Reddit Share

Support Me

Buy Me A Coffee