C#
Completed
-
Section 1: Getting Started
-
Section 2: Core Syntax
-
Section 3: Object-Oriented C#
-
Section 4: Working with Data
-
Section 5: Error Handling
-
Section 6: Delegates and Events
-
Section 7: Async Programming
-
Section 8: More Language Features
-
Section 9: File I/O and Serialization
-
Section 10: Networking in .NET
-
Section 11: The .NET Ecosystem
-
Section 12: Memory and Performance
-
Section 13: Concurrency Beyond Async
-
Section 14: Reflection and Attributes
-
Section 15: Testing and Best Practices
-
Section 16: Design Patterns in C#
-
Section 17: Standard Library Deep Dive
-
Section 18: Data Structures and Algorithms in C#
-
Section 19: GUI and Desktop Development Overview
-
Section 20: Practical Projects
-
Section 21: More Practice Exercises
-
Section 22: More Standard Library and Text Processing
-
Section 23: More Design Patterns
-
Section 24: More Projects
-
Section 25: Interview Practice
-
Section 26: C# Keywords Reference (Modifiers)
-
Section 27: C# Keywords Reference (Statements)
-
Section 28: C# Keywords Reference (Operators)
-
Section 29: BCL: System.Collections.Generic
-
Section 30: BCL: System.Linq
-
Section 31: BCL: System.Threading
-
Section 32: BCL: System.IO
-
Section 33: BCL: System.Text and System.Text.Json
-
Section 34: BCL: System.Net.Http
-
Section 35: C# Language Specification Topics
-
Section 36: More Practice Exercises
-
Section 37: More Async Patterns
-
Section 38: More BCL: System.Reflection and System.Diagnostics
-
Section 39: Nullable Reference Types In Depth
-
Section 40: C# Records and Pattern Matching In Depth
-
Section 41: Dependency Injection Deep Dive
-
Section 42: More Interview and Whiteboard Practice
225: Invoking Methods Dynamically via Reflection
Imagine you're walking into a high-end restaurant that has a "Chef's Choice" menu. Instead of ordering a specific dish you can see on the page, you tell the waiter, "I want the specialty for today," or you give them a specific code from a voucher. You don't know exactly how the chef is going to prepare the meal, or even what the recipe is, but you know that if you provide the right name, the kitchen will find the corresponding recipe and execute it.
In standard C#, we usually call methods explicitly: myObject.DoSomething(). That's like ordering the salmon—you know exactly what you're getting at compile time. Reflection is like that "Chef's Choice" order. You provide a string (the name of the method) at runtime, and you tell the .NET runtime, "Find the method that matches this name and run it for me."
Here is how that maps to the code:
- The Menu is the
Typeof the class. It lists everything the class is capable of doing. - The Order is the string name of the method you're looking for.
- The Recipe is the
MethodInfoobject. This isn't the method running yet; it's the metadata describing how to run it. - The Cooking is the
Invokecall, where the runtime actually executes the logic on a specific instance of the class.
Hunting for Methods in the Metadata
To do this, we need the System.Reflection namespace. Let's say you're building a game console where an admin can type commands like "KickPlayer" or "MutePlayer" into a text box. You don't want a giant switch statement with 500 cases; you just want to call the method that matches the text they typed.
using System;
using System.Reflection;
public class GameAdmin
{
public void KickPlayer(string playerName)
{
Console.WriteLine($"Player {playerName} has been kicked from the server.");
}
public void MutePlayer(string playerName)
{
Console.WriteLine($"Player {playerName} is now muted.");
}
}
// Inside your execution logic:
GameAdmin admin = new GameAdmin();
string commandFromUser = "KickPlayer"; // This would normally come from a UI text box
string targetPlayer = "NoobMaster69";
// 1. Get the Type of the object
Type type = admin.GetType();
// 2. Find the MethodInfo by name
MethodInfo method = type.GetMethod(commandFromUser);
if (method != null)
{
// 3. Invoke the method on the 'admin' instance with the required parameters
method.Invoke(admin, new object[] { targetPlayer });
}
else
{
Console.WriteLine("Command not found!");
}
Handling the 'Gotchas' of Dynamic Invocation
I've spent way too many hours debugging reflection because I forgot that Invoke is a bit of a "blind" operation. Since the compiler can't check if the method exists or if the arguments are correct until the code is actually running, it wraps everything in a TargetInvocationException. If the method you're calling throws an error, reflection catches it and wraps it in that exception. You'll need to check the InnerException property to see what actually went wrong inside the method.
Also, keep in mind that GetMethod only finds public methods by default. If you're trying to trigger a private method (which, honestly, you should do sparingly), you'll need to pass BindingFlags to the GetMethod call, like this: type.GetMethod("SecretMethod", BindingFlags.NonPublic | BindingFlags.Instance).
The Performance Trade-off
I'll be honest with you: reflection is slow. Much slower than a direct method call. The runtime has to search through the metadata, verify security permissions, and unbox arguments. If you're calling a reflected method once every few seconds in response to a user click, you'll never notice. If you're calling it 10,000 times per second inside a game loop, your frame rate will tank. In those cases, we'd look at delegates or compiled expressions, but for most "plug-and-play" architectural needs, MethodInfo.Invoke is your best friend.
📋 Practical Task
Building a Dynamic Smart-Home Command Processor
You are tasked with creating a system that controls a smart home. Instead of hard-coding every single device action, you need to create a processor that can call any public method on a SmartHomeDevice class based on a string command provided by a simulated remote control.
Requirements:
- Create a class named
SmartHomeDevicewith at least three public methods:ToggleLights(bool status),SetTemperature(int temp), andLockDoors(). Each should simply print a message to the console confirming the action. - In your
Mainmethod, create an instance ofSmartHomeDevice. - Create a string array of "commands" to simulate a sequence of remote button presses. For example:
"ToggleLights","LockDoors","SetTemperature". - Loop through these commands. For each command, use Reflection to find the corresponding method in the
SmartHomeDeviceclass and invoke it. - Challenge: Since some methods take arguments (like
SetTemperature) and some don't (likeLockDoors), implement a simple check or a hard-coded set of parameters to ensure theInvokecall doesn't crash when the method requires arguments.
There are no comments for now.