Share via


C# Code Reflection

This article is regarding Code Reflection in C#.

Introduction

Reflection is the ability of managed code to read its own metadata.

You can use reflection to 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.

If you are using attributes in your code, reflection enables you to access them.

Uses of Code Reflection

Below are some of the uses of code reflection:

  1. Check the type of an object at run-time using MetaData
  2. Examining and instantiating types in an assembly.
  3. Dynamically create type instances and dynamically invoke the methods, fields, properties in created instances.
  4. For performing late binding and accessing methods on types created at run time.

Classes used in this article

This article makes use the the following classes belo

public string  Name { get; set; }
 public int  price{ get; set; }
 public List<string> Extras{ get; set; }
 
 public Burger()
 {
 Extras = new  List<string>();
 }
 
 }
 
 public class  Pizza
 {
 public string  Name { get; set; }
 public int  price { get; set; }
 public List<string> Toppings { get; set; }
 
 public Pizza()
 {
 Toppings = new  List<string>();
 }
 
 public string  cook()
 {
 return "Cooking Pizza " + Name;
 }
 
 public string  cook(string  mins)
 {
 return "Cooking Pizza " + Name + " for "+mins+" Mins";
 }
 }

Getting Type data of an Object

To obtain the Type of an object** **statically at compile time, typeof method can be used. 

 var pizza = new  Pizza();
 Type t = typeof(Pizza);

 To obtain the Type of an object** **dynamically at run time, GetType method can be used.

  Type t1 = pizza.GetType();

From a Type, several useful information can be obtained about an object, such as its name and assembly. 

 Console.WriteLine(t1.Name); //Pizza
 Console.WriteLine(t1.Assembly); //Reflection, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null

Creating an Instance of a type

To create an instance of a type, the method **Activator.CreateInstance **can be used. 

This method creates an instance of the specified type using the constructor that best matches the specified parameters. 

Activator.CreateInstance can be used in 2 ways as described below:

a. Creates an instance of the specified type using that type's default constructor.

var newpizza = (Pizza)Activator.CreateInstance(typeof(Pizza));

b. Creates an instance of the type designated by the specified generic type parameter, using the parameterless constructor.

var newpizza1 = (Pizza)Activator.CreateInstance<pizza>();

Example 1: Creating an Object Dynamically.

The example below demonstrates how to create a Pizza object dynamically, retrieve its properties and assign their values.  

Step 1. Creating the instance of the Type Pizza.

var newpizza = (Pizza)Activator.CreateInstance(typeof(Pizza));

Step 2. Retrieving its properties.

The GetProperties Method, searches for the properties of the current Type, using the specified binding constraints.

  PropertyInfo[] properties = typeof(Pizza).GetProperties();
 
 PropertyInfo NameProperty = null;
 PropertyInfo PriceProterty = null;
 PropertyInfo ToppingProperty = null; 
  
 foreach (var property in properties)
 {
 if (property.Name.Equals("Name", StringComparison.CurrentCulture))
 NameProperty = property;
 
 else if  (property.Name.Equals("price", StringComparison.CurrentCulture))
 PriceProterty = property;
 
 else if  (property.Name.Equals("Toppings", StringComparison.CurrentCulture))
 ToppingProperty = property;
 }

Step 3: Setting the value of each property.

NameProperty.SetValue(newpizza, "MarlinPizza");
PriceProterty.SetValue(newpizza, 40);
ToppingProperty.SetValue(newpizza, new  List<string>() { "cheese",  "meat" });

Getting the value of a Property from an Object

var HawaiianPizza = new  Pizza()
{
 Name = "HawaiianPizza",
 price = 50,
 Toppings = new  List<string>(){"cheese","meat"}
};

Step 1: Get the type of the object.

var type = HawaiianPizza.GetType();

Step 2: Get the required property.

var property = type.GetProperty("Name");

Step 3: Get the value of the property.

var value = property.GetValue(HawaiianPizza); //value = "HawaiianPizza"

Invoking methods from an Object

Step 1: Get the type of the object.

var type = HawaiianPizza.GetType();

Step 2: Get the method needed.

In this example, there 2 methods with the same name.

To get the method having no parameter, an empty array of type Type should be passed.

var method = type.GetMethod("cook", new  Type[] { });

To get the method having a string parameter, pass the parameter in an array like below

var method = type.GetMethod("cook", new  Type[] { typeof(string) });

Step 3: Invoking the method.  

To invoke the method with no parameter, null should be passed to the invoke method.

var value = (string)method.Invoke(HawaiianPizza,null);

To invoke methods requiring parameters, the parameters can be passed in an array like below

var value = (string)method.Invoke(HawaiianPizza, new  string[] {"5"});

Example 2: A generic method with different behavior based on Object Type

The example below shows how the output can be different on whether a Pizza or a Burger is passed to the PrintReceipt Method.

 var HawaiianPizza = new  Pizza()
 {
 Name = "HawaiianPizza",
 price = 50,
 Toppings = new  List<string>() { "cheese",  "meat" }
 };
 
 var BigBurger = new  Burger()
 {
 Name = "BigBurger",
 price = 100,
 Extras = new  List<string>() { "Chips",  "Cheese" }
 };
 
 
 PrintReceipt(HawaiianPizza);
 PrintReceipt(BigBurger);
 
 
 
public static  void PrintReceipt(Object obj)
{
 var type = obj.GetType();
 
 if (type.Name == "Pizza")
 { 
 Console.WriteLine("Printing receipt for: " + type.GetProperty("Name").GetValue(obj));
 
 Console.WriteLine("Toppings: ");
 
 List<string> toppings = (List<string>)type.GetProperty("Toppings").GetValue(obj);
  
 foreach(var topping in  toppings)
 Console.WriteLine(topping);
 
 Console.WriteLine("Price: " + type.GetProperty("price").GetValue(obj));
  
 }
 
 if (type.Name == "Burger")
 {
 Console.WriteLine("Printing receipt for: " + type.GetProperty("Name").GetValue(obj));
 
 Console.WriteLine("Extras: ");
 
 List<string> toppings = (List<string>)type.GetProperty("Extras").GetValue(obj);
 
 foreach (var topping in toppings)
 Console.WriteLine(topping);
 
 Console.WriteLine("Price: " + type.GetProperty("price").GetValue(obj));
  
 }
 
 
}

References