In the world of programming, reflection is a powerful feature that allows you to inspect and manipulate your code's structure at runtime. This capability is particularly useful when you need to work with types dynamically or when interfacing with external libraries where the type information might not be known until runtime.
C# provides a rich set of reflection APIs in the System.Reflection namespace, enabling developers to explore assemblies, modules, types, methods, properties, and more. This tutorial will guide you through the basics of using reflection in C#, focusing on how to inspect and manipulate types at runtime.
Reflection is a feature that allows your code to examine and modify its structure and behavior. In simpler terms, it lets you look inside your program's components (like classes, methods, properties) and interact with them dynamically.
Let's start by examining how to get basic information about a type using reflection. We'll create a simple class and inspect its properties and methods.
using System;
using System.Reflection;
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public void SayHello()
{
Console.WriteLine($"Hello, my name is {Name} and I am {Age} years old.");
}
}
class Program
{
static void Main(string[] args)
{
// Create an instance of the Person class
Person person = new Person { Name = "John", Age = 30 };
// Get the type of the person object
Type personType = person.GetType();
// Display the name of the type
Console.WriteLine($"Type: {personType.Name}");
// Get and display all properties of the type
PropertyInfo[] properties = personType.GetProperties();
foreach (PropertyInfo property in properties)
{
Console.WriteLine($"Property: {property.Name}, Type: {property.PropertyType}");
}
// Get and invoke a method dynamically
MethodInfo sayHelloMethod = personType.GetMethod("SayHello");
sayHelloMethod.Invoke(person, null);
}
}
<OutputBlock>
{`Type: Person
Property: Name, Type: System.String
Property: Age, Type: System.Int32
Hello, my name is John and I am 30 years old.`}
</OutputBlock>
### Advanced Reflection: Creating Instances Dynamically
Reflection can also be used to create instances of types dynamically. This is particularly useful when you need to instantiate objects based on type names that are only known at runtime.
```csharp
using System;
using System.Reflection;
class Program
{
static void Main(string[] args)
{
// Define the fully qualified name of the class we want to create
string className = "Person";
string assemblyName = "YourAssemblyName"; // Replace with your actual assembly name
// Get the type from the assembly
Type personType = Assembly.Load(assemblyName).GetType(className);
if (personType != null)
{
// Create an instance of the type
object personInstance = Activator.CreateInstance(personType);
// Set properties dynamically
PropertyInfo nameProperty = personType.GetProperty("Name");
PropertyInfo ageProperty = personType.GetProperty("Age");
nameProperty.SetValue(personInstance, "Jane");
ageProperty.SetValue(personInstance, 25);
// Invoke a method dynamically
MethodInfo sayHelloMethod = personType.GetMethod("SayHello");
sayHelloMethod.Invoke(personInstance, null);
}
else
{
Console.WriteLine($"Type {className} not found in assembly {assemblyName}");
}
}
}
<OutputBlock>
{`Hello, my name is Jane and I am 25 years old.`}
</OutputBlock>
### Using Attributes with Reflection
Attributes are metadata that you can attach to types, methods, properties, etc. You can use reflection to inspect these attributes at runtime.
```csharp
using System;
using System.Reflection;
// Define a custom attribute
[AttributeUsage(AttributeTargets.Class)]
public class DescriptionAttribute : Attribute
{
public string Description { get; }
public DescriptionAttribute(string description)
{
Description = description;
}
}
// Apply the custom attribute to a class
[Description("A simple person class")]
public class Person
{
// Class implementation remains the same as before
}
class Program
{
static void Main(string[] args)
{
// Get the type of the Person class
Type personType = typeof(Person);
// Check if the Description attribute is present and display it
object[] attributes = personType.GetCustomAttributes(typeof(DescriptionAttribute), false);
foreach (var attr in attributes)
{
DescriptionAttribute descriptionAttr = attr as DescriptionAttribute;
Console.WriteLine($"Description: {descriptionAttr.Description}");
}
}
}
<OutputBlock>
{`Description: A simple person class`}
</OutputBlock>
## What's Next?
Now that you have a good understanding of reflection in C#, the next step is to explore **Attributes in C#**. Attributes are a powerful feature that allows you to add metadata to your code, which can be inspected using reflection. This will open up even more possibilities for dynamic and flexible programming.
By mastering both reflection and attributes, you'll be well-equipped to handle complex scenarios where static typing might not suffice, enabling you to write more robust and adaptable applications.
Happy coding!