[C#] Reflection made simple.

Reflection in C# is a powerful mechanism that allows programs to introspect and manipulate themselves.This feature allows inspecting and modifying a program's types at runtime. It enables obtaining information about types, members, methods, and properties of an object, and dynamically invoking methods or accessing properties.

A definition for Reflection

Reflection is the process by which a computer program can observe and modify its own structure and behavior. In C#, this is achieved using the System.Reflection namespace. It provides classes that allow you to interrogate and manipulate assemblies, modules, and types.

Exploring Assemblies

An assembly is a compiled code library used by .NET applications. With reflection, you can load an assembly and browse through its modules and types. Consider this example:

using System;
using System.Reflection;

class ExploreAssembly{
    static void Main(){
        Assembly asm = Assembly.GetExecutingAssembly();
        Console.WriteLine($"Assembly Name: {asm.FullName}");

        foreach (Type type in asm.GetTypes()){
            Console.WriteLine($"Type: {type.Name}");
        }
    }
}

This code prints the name of the current assembly and lists all types defined in it.

Inspecting Types and Members

Reflection allows you to explore a type's members, such as methods, properties, fields, and events. Here’s how you can list all methods of a type:

using System;
using System.Reflection;

class MyClass{
    public int MyMethod() { return 42; }
}

class ExploreClassMethods{
    static void Main(){
        Type type = typeof(MyClass);
        foreach (MethodInfo method in type.GetMethods()){
            Console.WriteLine($"Method: {method.Name}");
        }
    }
}

This example prints all the methods of MyClass.

Dynamic Object Creation and Method Invocation

Reflection enables the creation of objects and invocation of methods at runtime. This flexibility is crucial for scenarios like plugin architectures. Here's an example:

using System;
using System.Reflection;

class MyClass{
    public void SayHello(string name){
        Console.WriteLine($"Hello, {name}!");
    }
}

class CreateAndUseInstance{
    static void Main(){
        Type type = typeof(MyClass);
        object obj = Activator.CreateInstance(type);
        MethodInfo method = type.GetMethod("SayHello");
        method.Invoke(obj, new object[] { "Gioele" });
    }
}

This code dynamically creates an instance of MyClass and calls the SayHello method.

Accessing Private Members

Reflection can access private members, offering a window into the internals of types. This capability should be used judiciously. Here’s an example:

using System;
using System.Reflection;

class MyClass{
    private int _secretNumber = 42;
}

class ExplorePrivate{
    static void Main(){
        MyClass myObject = new MyClass();
        Type type = myObject.GetType();

        FieldInfo field = type.GetField("_secretNumber", BindingFlags.NonPublic | BindingFlags.Instance);
        Console.WriteLine($"Secret Number: {field.GetValue(myObject)}");
    }
}

This code accesses a private field _secretNumber from an instance of MyClass.

6\. Attributes and Custom Metadata

Reflection is instrumental in working with custom attributes – metadata added to code elements. Here’s how to read custom attributes:

using System;
using System.Reflection;

[AttributeUsage(AttributeTargets.Class)]
public class MyCustomAttribute : Attribute{
    public string Description { get; set; }
}

[MyCustomAttribute(Description = "A sample class.")]
class MyClass { }

class ExploreMetadata{
    static void Main(){
        Type type = typeof(MyClass);
        MyCustomAttribute attr = (MyCustomAttribute)Attribute.GetCustomAttribute(type, typeof(MyCustomAttribute));
        Console.WriteLine($"Description: {attr.Description}");
    }
}

This code retrieves the Description property of the MyCustomAttribute applied to MyClass.

Reflection is among the most powerful features in C#, but it must be used with caution due to its complexity. Inadequate understanding of accessing fields, properties, and methods leads to the development of insecure or unsafe code. Some bugs resulting from improper use of reflection are nearly impossible to detect and correct.


You'll only receive email when they publish something new.

More from GSLF
All posts