Skip to Content
Course content

225: Invoking Methods Dynamically via Reflection

Click on the "Edit" button in the top corner of the screen to edit your slide content.

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 Type of 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 MethodInfo object. This isn't the method running yet; it's the metadata describing how to run it.
  • The Cooking is the Invoke call, 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 SmartHomeDevice with at least three public methods: ToggleLights(bool status), SetTemperature(int temp), and LockDoors(). Each should simply print a message to the console confirming the action.
  • In your Main method, create an instance of SmartHomeDevice.
  • 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 SmartHomeDevice class and invoke it.
  • Challenge: Since some methods take arguments (like SetTemperature) and some don't (like LockDoors), implement a simple check or a hard-coded set of parameters to ensure the Invoke call doesn't crash when the method requires arguments.
Rating
0 0

There are no comments for now.

to be the first to leave a comment.