Reflection and Introspection in C#: How to Look Inside Your Code

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Introduction: The Magic of Reflection

Imagine you are writing code that can "look" at itself. Not like in a funhouse mirror, but like in an X-ray machine — seeing the structure, properties, methods, even invoking them without knowing the class name at compile time. This is not magic, it is reflection in C# and its "younger sister" — C# introspection.



Why is this needed? Imagine you are writing a plugin system, a JSON deserializer, or dynamic method invocation. Without reflection, you would have to write a ton of if-else statements. But with it, just a couple of lines are enough. Sounds intriguing? Let's dive in.



In this article, we won't just go through the theory. We will write real code examples that you can use immediately in your projects. You will learn how to get information about any type, create an object "out of thin air", call a private method, and even read attributes. And all of this — in C#, a language loved for its rigor and power.



What are Reflection and Introspection in C#? The Difference Between the Concepts

These terms are often used as synonyms, but there is a fine line between them:

  • C# Introspection — is the ability of a program to observe its own structure. You can find out what fields a class has, what methods it contains, what attributes are attached. But you don't change anything.
  • C# Reflection — is a broader concept. It includes introspection, plus the ability to interact with the code: calling methods, creating objects, changing field values.

Simply put: introspection is "to look", reflection is "to look and touch". In C#, both functions are handled by the System.Reflection namespace. This is your main tool.



Practical Example: Getting Information About a Type (Type)

Everything starts with the Type class. This is the foundation of reflection. You can get it in three ways:

// Method 1: via typeof()Type typeFromKeyword = typeof(string);

// Method 2: via instance .GetType()string example = "Hello, world!";Type typeFromInstance = example.GetType();

// Method 3: via AssemblyType typeFromAssembly = Assembly.GetExecutingAssembly().GetType("System.String");


Now, having a Type object, we can find out everything about the class. Let's write a useful method for introspection:



using System;using System.Reflection;

public class Inspector{ public static void ShowTypeInfo(Type type) { Console.WriteLine($"=== Type Information: {type.Name} ==="); Console.WriteLine($"Full Name: {type.FullName}"); Console.WriteLine($"Is it a class? {type.IsClass}"); Console.WriteLine($"Is it abstract? {type.IsAbstract}"); Console.WriteLine($"Base Class: {type.BaseType?.Name}"); Console.WriteLine("Public Properties:"); foreach (PropertyInfo prop in type.GetProperties()) { Console.WriteLine($" - {prop.PropertyType.Name} {prop.Name}"); } Console.WriteLine("Public Methods:"); foreach (MethodInfo method in type.GetMethods()) { Console.WriteLine($" - {method.ReturnType.Name} {method.Name}({string.Join(", ", method.GetParameters().Select(p => $"{p.ParameterType.Name} {p.Name}"))})"); } }}

// UsageInspector.ShowTypeInfo(typeof(List<int>));/* Output:=== Type Information: List`1 ===Full Name: System.Collections.Generic.List`1[[System.Int32, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]Is it a class? TrueIs it abstract? FalseBase Class: Object

Public Properties: - Int32 Capacity - Int32 Count

Public Methods: - Void Add(Int32 obj) - Void Clear() - Boolean Contains(Int32 item) ... and many others*/


This is pure intro

Blogs

Book Recommendations