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:
- Check the type of an object at run-time using MetaData
- Examining and instantiating types in an assembly.
- Dynamically create type instances and dynamically invoke the methods, fields, properties in created instances.
- 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));
}
}