Reflection In C#: 4 Simple But Powerful Code Examples
Tags: csharp, coding, programming, dotnet
Published: 2024-03-05 17:00:00

The post [Reflection in C#: 4 Code Simple But Powerful Code Examples](https://www.devleader.ca/2024/02/26/reflection-in-c-4-code-simple-but-powerful-code-examples/) appeared first on [Dev Leader](https://www.devleader.ca).

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.

Reflection in C# provides us with the ability to examine types, their members, and invoke methods dynamically, opening up a world of possibilities for creative programs. In this article, I’ll provide you with 4 simple code examples illustrating how reflection works in C#.

---

## Example 1: Retrieving Type Information Using Reflection in CSharp

Reflection in C# allows us to examine and manipulate types at runtime. It gives us the ability to retrieve information about classes, interfaces, methods, properties, and more. Understanding how to retrieve types using reflection is important for more complex and creative applications in C#.

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:

```csharp
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`[operator to get the type](https://www.devleader.ca/2023/05/31/implicit-operators-in-c-and-how-to-create-a-multi-type/) of the `Car` class. Then, we can [access various information about the type](https://www.devleader.ca/2023/01/29/simple-secrets-to-access-to-the-dotnet-record-type/). In this example, we retrieve the type’s name, all public methods, and all properties. Running this code will output the following:

```csharp
Type Name: Car
Methods:
- StartEngine
- StopEngine
Properties:
- Make
- Model
```

Retrieving types using reflection can be useful in a variety of scenarios. For example, you might want to [dynamically load](https://www.devleader.ca/2023/09/15/blazor-plugin-architecture-how-to-manage-dynamic-loading-lifecycle/) and instantiate classes based on user input or configuration data. Reflection also enables you to inspect the structure and behavior of code at runtime, and this opens up some doors when you need to make decisions based on information that you don’t have at compile time. [See how this works in this video tutorial](https://youtu.be/7xWaSuPn2I8):

{% embed https://youtu.be/7xWaSuPn2I8 %}

{% embed https://devleaderweekly.substack.com/embed %}

---

## [Example 2: Accessing Non-Public Members](https://youtu.be/7xWaSuPn2I8) Using Reflection in CSharp

We previously saw how we could access things like public methods and properties that are available on types. As mentioned, this can have many helpful use-cases but it doesn’t \*quite\* feel like the scary stories we might have heard about reflection. Let’s change that up a bit.

While reflection in C# allows us to look up this information, we can also look up non-public information about types. That’s right. All of that effort that someone put in place to use private/protected and hide details from us on the outside? Gone. We can see everything we want! Muahaha! Oh, right — with great [power comes great responsibility](https://www.devleader.ca/2023/08/11/async-lazy-in-c-with-great-power-comes-great-responsibility/). No more evil laughter.

Here’s an example code snippet that demonstrates how to access non-public members using reflection:

```csharp
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 [private field](https://www.devleader.ca/2013/07/22/keep-your-fields-private/)`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 members that are non-public. We combine these two categories of members together [using flag enums](https://www.devleader.ca/2023/11/15/enums-in-csharp-a-simple-guide-to-expressive-code/), which you can [learn more about here in this video](https://www.youtube.com/watch?v=_yUOrzTCpGU):

{% embed https://www.youtube.com/watch?v=_yUOrzTCpGU %}

---

## Example 3: Modifying Objects Using Reflection

Reflection in C# not only allows us to inspect and retrieve information about objects, but it also gives us the power to modify their data and behavior dynamically at runtime. This means that we can, at runtime, get a member by name (and other conditions) and then make modifications — effectively bypassing a lot of the compile-time checks we normally get. And… we can combine that with the non-public access we just saw! Keep that maniacal evil laughter under control…

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:

```csharp
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.

```csharp
// 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!

While being able to modify objects dynamically can be incredibly powerful, it also comes with some risks and considerations. Modifying objects using reflection can introduce complexity and potential pitfalls (read that as: “will likely break things”), such as breaking encapsulation and violating the intended behavior of the object. It’s important to exercise caution and ensure that the modifications made using reflection align with the design and requirements of the system — this \*probably\* shouldn’t be your first course of action for many things. [Learn more about private access and modification in this video tutorial](https://youtu.be/3Qstc-ND8Oo):

{% embed https://youtu.be/3Qstc-ND8Oo %}

---

## [Example 4: Creating Objects Using Reflection](https://youtu.be/3Qstc-ND8Oo)

[Reflection in C# allow](https://youtu.be/3Qstc-ND8Oo)s us to [create instances of types](https://www.devleader.ca/2023/05/31/implicit-operators-in-c-and-how-to-create-a-multi-type/) dynamically. This means that we can create objects of a certain class without knowing the class name at compile-time. This flexibility can be particularly useful in scenarios where we need to dynamically instantiate objects based on runtime data or configuration.

To create an object dynamically using reflection, we need to follow a few steps:

* We need to obtain a Type object that represents the class we want to create an instance of. We can do this by using the `Type.GetType()` method and passing the fully qualified name of the class as a string.
    
* We can use the `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.
    

Let’s take a look at an example:

```csharp
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).

Creating objects dynamically using reflection can be useful in various scenarios, including:

* [A plugin system where we want to load different plugins at runtime](https://www.devleader.ca/2023/09/15/blazor-plugin-architecture-how-to-manage-dynamic-loading-lifecycle/). By using reflection, we can dynamically create instances of the plugin classes based on configuration or user input.
    
* Dynamic object creation when working with deserialization. For example, if we receive JSON or XML data and need to map it to different classes based on the data content, reflection in C# can help us create the appropriate objects dynamically.
    

Remember to handle exceptions and ensure proper error-checking when working with reflection and dynamically creating objects! It’s easy to forget that reflection opens some funky doors that we really need to be careful with.

---

## Showcase of Reflection in CSharp

Reflection in C# is a powerful tool that every C# developer should get familiar with because even if you don’t need to use it regularly, it’s helpful to understand. Reflection allows us to examine and manipulate objects at runtime, providing us with great flexibility and control over code in some [creative situations — like plugin loading](https://www.devleader.ca/2023/09/07/plugin-architecture-design-pattern-a-beginners-guide-to-modularity/)! By leveraging reflection, we can [dynamically load](https://www.devleader.ca/2023/09/15/blazor-plugin-architecture-how-to-manage-dynamic-loading-lifecycle/) types, query and invoke methods, access properties, and even create new objects.

Throughout this article, we explored four code examples that showcased how you can leverage reflection in C#. We discussed how to iterate through members, inspect things that aren’t publicly available, retrieve and set property values dynamically, and dynamically create instances of objects. If you found this useful and you’re looking for more learning opportunities, consider [subscribing to my free weekly software engineering newsletter](https://subscribe.devleader.ca) and check out my [free videos on YouTube](https://www.youtube.com/@devleader?sub_confirmation=1)!

{% embed https://devleaderweekly.substack.com/embed %}

---

## **Want More Dev Leader Content?**

* Follow along on this platform if you haven’t already!    
* Subscribe to my free weekly software engineering and dotnet-focused newsletter. I include exclusive articles and early access to videos:  
    [**SUBSCRIBE FOR FREE**](https://subscribe.devleader.ca/)    
* Looking for courses? Check out my offerings:  
    [**VIEW COURSES**](https://devleader.ca/courses)    
* E-Books & other resources:  
    [**VIEW RESOURCES**](https://products.devleader.ca/)    
* Watch hundreds of full-length videos on my YouTube channel:  
    [**VISIT CHANNEL**](https://youtube.com/@devleader?sub_confirmation=1)    
* Visit my website for hundreds of articles on various software engineering topics (including code snippets):  
    [**VISIT WEBSITE**](https://devleader.ca/)    
* Check out the repository with many code examples from my articles and videos on GitHub:  
    [**VIEW REPOSITORY**](https://github.com/ncosentino/DevLeader)