Reflection and Attributes

Back

Loading concept...

C# Reflection and Attributes: The Magic Mirror of Code 🪞

The Big Picture

Imagine you have a magic mirror. This mirror doesn’t show your face—it shows you everything about any object you look at. What it’s made of. What it can do. Even its secrets!

In C#, Reflection is that magic mirror. It lets your program look at itself and other programs. It can see classes, methods, and properties—even ones you didn’t know existed!

Attributes are like sticky notes you put on things. “This method is old!” or “Don’t use this!” They add extra information without changing what something does.


🌟 Reflection Basics: Looking in the Magic Mirror

What is Reflection?

Reflection is when your program can look at itself. It’s like a robot that can open its own chest and see all its parts.

Simple Example:

  • You have a toy box (a class)
  • Normally, you just play with toys
  • With reflection, you can count the toys, read their labels, even find hidden toys!

Why Use Reflection?

  • Discovery: Find out what’s inside a class you didn’t write
  • Flexibility: Do things at runtime you didn’t plan at compile time
  • Magic Tools: Build frameworks, serializers, and plugins

Getting Started

Everything starts with the Type class. It’s like getting the blueprint of any object.

// Get the type of any object
string name = "Hello";
Type myType = name.GetType();

Console.WriteLine(myType.Name);
// Output: String

You can also get a type without an object:

Type stringType = typeof(string);
Type intType = typeof(int);

🎯 Think of it like this: GetType() asks “What are you?” and typeof() asks “What is this thing called?”


🔍 Type Inspection: Reading the Blueprint

Now that we have the mirror, let’s see what it shows us!

Seeing Properties

Properties are like labels on a box. They tell you what’s inside.

Type personType = typeof(Person);

// Get all public properties
PropertyInfo[] props =
    personType.GetProperties();

foreach (var prop in props)
{
    Console.WriteLine(prop.Name);
}

Seeing Methods

Methods are like buttons on a remote. Each one does something.

Type personType = typeof(Person);

// Get all public methods
MethodInfo[] methods =
    personType.GetMethods();

foreach (var method in methods)
{
    Console.WriteLine(method.Name);
}

Seeing Fields

Fields are like secret pockets. They hold private data.

// Get private fields too!
FieldInfo[] fields = personType
    .GetFields(BindingFlags.NonPublic
             | BindingFlags.Instance);

The BindingFlags Toolbox

BindingFlags helps you filter what you see:

Flag What It Finds
Public Public members
NonPublic Private/protected
Instance Regular members
Static Static members

Combine them with | (pipe):

BindingFlags all =
    BindingFlags.Public
  | BindingFlags.NonPublic
  | BindingFlags.Instance;

🏭 Dynamic Instantiation: Creating Objects at Runtime

Here’s where the magic gets really cool. You can create objects without knowing their type when you write the code!

Why Is This Useful?

Imagine a game with 100 enemy types. Instead of writing code for each one, you can say: “Create whatever enemy the player needs right now!”

Using Activator.CreateInstance

// Create an object from a Type
Type carType = typeof(Car);
object myCar = Activator
    .CreateInstance(carType);

// Now myCar is a real Car!

Creating with Constructor Arguments

// Car has constructor: Car(string color)
object redCar = Activator
    .CreateInstance(
        typeof(Car),
        new object[] { "Red" }
    );

Creating from a Type Name String

This is super powerful for plugins and configuration:

// From full type name
Type type = Type.GetType(
    "MyNamespace.Car"
);
object car = Activator
    .CreateInstance(type);

Calling Methods Dynamically

Once you create an object, you can call its methods too:

// Get the method
MethodInfo driveMethod =
    carType.GetMethod("Drive");

// Call it on our object
driveMethod.Invoke(myCar, null);
graph TD A["Get Type"] --> B["Create Instance"] B --> C["Get Method Info"] C --> D["Invoke Method"] style A fill:#e3f2fd style B fill:#bbdefb style C fill:#90caf9 style D fill:#64b5f6

🏷️ Attributes Basics: Sticky Notes for Code

What Are Attributes?

Attributes are like labels you stick on your code. They don’t change what the code does—they add extra information ABOUT the code.

Real Life Example:

  • A jar has jam inside (the code)
  • The label says “Strawberry, Made in 2024, Organic” (attributes)
  • The label doesn’t change the jam—it describes it!

Creating an Attribute

// Simple attribute
[Serializable]
public class Person { }

// Attribute with value
[Obsolete("Use NewMethod instead")]
public void OldMethod() { }

Reading Attributes with Reflection

Here’s where reflection and attributes team up:

Type type = typeof(Person);

// Check if it has an attribute
bool isSerializable =
    Attribute.IsDefined(
        type,
        typeof(SerializableAttribute)
    );

// Get attribute details
var attrs = type
    .GetCustomAttributes(true);

Making Your Own Attribute

You can create custom sticky notes!

// Define your attribute
public class AuthorAttribute
    : Attribute
{
    public string Name { get; }

    public AuthorAttribute(string name)
    {
        Name = name;
    }
}

// Use it
[Author("Alice")]
public class MyClass { }

📦 Built-in Attributes: The Ready-Made Labels

C# comes with many useful attributes. Here are the most important ones:

[Obsolete] - “This is Old!”

Tells developers: “Don’t use this anymore!”

[Obsolete("Use NewMethod()")]
public void OldMethod() { }

// Compiler shows warning!

[Serializable] - “Can Be Saved!”

Marks a class as saveable to files or network:

[Serializable]
public class GameSave
{
    public int Level;
    public int Score;
}

[Conditional] - “Only Sometimes!”

Method only runs in certain builds:

[Conditional("DEBUG")]
public void DebugLog(string msg)
{
    Console.WriteLine(msg);
}

[AttributeUsage] - “Rules for Attributes!”

Controls where your custom attribute can go:

[AttributeUsage(
    AttributeTargets.Class |
    AttributeTargets.Method)]
public class MyAttribute
    : Attribute { }

[Flags] - “Can Combine Values!”

For enums that can mix values:

[Flags]
enum Permissions
{
    Read = 1,
    Write = 2,
    Execute = 4
}

// Can combine: Read | Write

Summary Table

Attribute What It Does
[Obsolete] Marks old code
[Serializable] Allows saving
[Conditional] Debug-only code
[AttributeUsage] Rules for attrs
[Flags] Combinable enums

🎯 Putting It All Together

Here’s a mini-story showing everything working together:

// 1. Create a class with attributes
[Author("Bob")]
[Serializable]
public class Hero
{
    public string Name { get; set; }

    [Obsolete("Use Attack()")]
    public void Fight() { }

    public void Attack() { }
}

// 2. Use reflection to explore it
Type heroType = typeof(Hero);

// 3. Create instance dynamically
object hero = Activator
    .CreateInstance(heroType);

// 4. Find and read attributes
var author = heroType
    .GetCustomAttribute<AuthorAttribute>();
Console.WriteLine(author.Name);
// Output: Bob

// 5. Call method dynamically
MethodInfo attack =
    heroType.GetMethod("Attack");
attack.Invoke(hero, null);
graph TD A["Define Class + Attributes"] --> B["Get Type via Reflection"] B --> C["Read Attributes"] B --> D["Create Instance"] D --> E["Call Methods"] style A fill:#c8e6c9 style B fill:#a5d6a7 style C fill:#81c784 style D fill:#66bb6a style E fill:#4caf50

🚀 Key Takeaways

  1. Reflection = Looking at code structure at runtime
  2. Type Inspection = Discovering properties, methods, fields
  3. Dynamic Instantiation = Creating objects without knowing type ahead of time
  4. Attributes = Metadata labels attached to code
  5. Built-in Attributes = Ready-made labels like [Obsolete] and [Serializable]

Remember the magic mirror analogy:

  • Reflection is the mirror 🪞
  • Type inspection is what you see in the mirror đź‘€
  • Dynamic instantiation is creating what you see 🏭
  • Attributes are sticky notes on the things you see 🏷️

You now have the power to make your code look at itself—and even create new parts on the fly. That’s real magic! ✨

Loading story...

Story - Premium Content

Please sign in to view this story and start learning.

Upgrade to Premium to unlock full access to all stories.

Stay Tuned!

Story is coming soon.

Story Preview

Story - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.