visit
Reflection in C# is a powerful feature that allows you to inspect and manipulate code at runtime. If that sounds like some fancy programming magic, it’s because it basically is. And you know what they say — with great power, comes great responsibility.
To retrieve types using reflection, we can use the Type
class from the System
namespace. The Type
class provides various methods and properties to work with types dynamically. Here’s an example code snippet that demonstrates how to retrieve types using reflection:
using System;
public class Program
{
public static void Main()
{
// Get the type of a class
Type carType = typeof(Car);
Console.WriteLine($"Type Name: {carType.Name}");
// Get all public methods of a class
MethodInfo[] methods = carType.GetMethods();
Console.WriteLine("Methods:");
foreach (MethodInfo method in methods)
{
Console.WriteLine($"- {method.Name}");
}
// Get all properties of a class
PropertyInfo[] properties = carType.GetProperties();
Console.WriteLine("Properties:");
foreach (PropertyInfo property in properties)
{
Console.WriteLine($"- {property.Name}");
}
}
}
public class Car
{
public string Make { get; set; }
public string Model { get; set; }
public void StartEngine()
{
Console.WriteLine("Engine started");
}
public void StopEngine()
{
Console.WriteLine("Engine stopped");
}
}
In the above code, we first use the typeof
of the Car
class. Then, we can . In this example, we retrieve the type’s name, all public methods, and all properties. Running this code will output the following:
Type Name: Car
Methods:
- StartEngine
- StopEngine
Properties:
- Make
- Model
See how this works in this video tutorial:
using System;
using System.Reflection;
public class Person
{
private string _name;
privateint Age { get; set; }
private void SayHello()
{
Console.WriteLine("Hello!");
}
}
public class Program
{
public static void Main()
{
Type personType = typeof(Person);
// Accessing a field using reflection
FieldInfo nameField = personType.GetField(
"_name",
BindingFlags.NonPublic | BindingFlags.Instance);
Console.WriteLine($"Field Name: {nameField.Name}");
// Accessing a private property using reflection
PropertyInfo ageProperty = personType.GetProperty(
"Age"
BindingFlags.NonPublic | BindingFlags.Instance);
Console.WriteLine($"Property Name: {ageProperty.Name}");
// Accessing a private method using reflection
MethodInfo sayHelloMethod = personType.GetMethod(
"SayHello",
BindingFlags.NonPublic | BindingFlags.Instance);
Console.WriteLine($"Method Name: {sayHelloMethod.Name}");
}
}
In the above code, we define a Person
class with a name
, a private property Age
, and a private method SayHello
. In the Main
method, we obtain the Type
object for the Person
class using typeof(Person)
. Using reflection, we can access the field, property, and method by specifying their names and using the GetField
, GetProperty
, and GetMethod
methods of the Type
type, respectively, to retrieve the corresponding members.
But the super important part here? The BindingFlags
enum. We can ask, for instance, non-public members. We combine these two categories of members together , which you can :
To illustrate how modifying objects using reflection works, let’s consider a scenario where we have a simple Person
class with properties representing their name and age:
public class Person
{
public string Name { get; set; }
// NOTE: this probably makes no sense to ever
// just have a private property like this here
// but it's just for demonstration
private int Age { get; set; }
public void PrintInfo()
{
Console.WriteLine($"{Name} - {Age} years old");
}
}
Now, let’s say we want to change the age of a Person
object dynamically based on some condition. With reflection, we can achieve this by accessing and modifying the Age
property at runtime.
// Create a new instance of the Person class
Person person = new Person()
{
Name = "Dev Leader",
};
// Get the Type object for the Person class
Type personType = typeof(Person);
// Get the PropertyInfo object for the Age property
PropertyInfo ageProperty = personType.GetProperty(
"Age",
BindingFlags.NonPublic | BindingFlags.Instance);
// Set the value of the Age property to 35
ageProperty.SetValue(person, 35);
// Prints "Dev Leader - 35 years old")
person.PrintInfo();
In this code example, we first create an instance of the Person
class. Then, using reflection, we obtain the Type
object for the Person
class. From the Type
object, we retrieve the PropertyInfo
object for the Age
property, which is private and not accessible to us traditionally from the outside. Finally, we use the SetValue
method of the PropertyInfo
object to modify the Age
property of the person
object to 35. When we ask the instance to print its info, we see the updated value!
Learn more about private access and modification in this video tutorial:
Type.GetType()
method and passing the fully qualified name of the class as a string.Activator.CreateInstance()
method to create an instance of the class. This method takes the Type object as a parameter and returns a new instance of the class. We can then cast this instance to the desired type and use it as needed.
string className = "MyNamespace.MyClass";
Type classType = Type.GetType(className);
object instance = Activator.CreateInstance(classType);
MyClass myObject = (MyClass)instance;
In the code above, we start by defining the fully qualified name of the class we want to create an instance of (MyNamespace.MyClass
). We then obtain the Type object by calling Type.GetType()
and passing the class name as a string. Next, we use Activator.CreateInstance()
to create a new instance of the class and cast it to the desired type (MyClass
in this case).