C#
functions
string manipulation
dynamic invocation
programming

Calling a function from a string in C

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

In C#, calling a method from a string usually means runtime dispatch based on user input, configuration, or message payloads. This is possible, but the safest approach is often not raw reflection. You should choose among reflection, delegate maps, or command pattern based on performance and safety requirements.

Reflection Based Invocation

Reflection can locate and invoke methods by name at runtime.

csharp
1using System;
2using System.Reflection;
3
4public class Calculator
5{
6    public int Add(int a, int b) => a + b;
7    public int Multiply(int a, int b) => a * b;
8}
9
10public class Program
11{
12    public static void Main()
13    {
14        var calc = new Calculator();
15        string methodName = "Add";
16
17        MethodInfo? method = typeof(Calculator).GetMethod(methodName);
18        if (method == null) throw new InvalidOperationException("Method not found");
19
20        object? result = method.Invoke(calc, new object[] { 3, 4 });
21        Console.WriteLine(result);
22    }
23}

This is flexible but slower than direct calls and can fail at runtime if signatures mismatch.

Faster And Safer Delegate Map

For known operations, map strings to delegates once and invoke directly.

csharp
1using System;
2using System.Collections.Generic;
3
4public class Program
5{
6    public static void Main()
7    {
8        var operations = new Dictionary<string, Func<int, int, int>>(StringComparer.OrdinalIgnoreCase)
9        {
10            ["add"] = (a, b) => a + b,
11            ["mul"] = (a, b) => a * b
12        };
13
14        string op = "mul";
15        int value = operations[op](6, 7);
16        Console.WriteLine(value);
17    }
18}

This pattern gives compile time safety for signatures and better runtime performance.

Command Pattern For Larger Systems

If behavior grows, model each action as a command class implementing a shared interface. Then map command names to implementations through dependency injection. This improves testability and avoids giant switch statements.

Reflection can still be used for dynamic plugin loading, but isolate it to bootstrapping rather than per request execution.

Security And Validation Concerns

Never invoke arbitrary method names directly from untrusted input. Always validate against an allow list of supported operations. Reflection without validation can expose internal APIs unintentionally.

Also validate argument count and type conversion before invocation. Runtime conversion failures are a common source of production errors in dynamic dispatch systems.

Performance Considerations

Reflection invocation allocates and performs metadata lookup. If repeated calls are needed, cache MethodInfo or compile delegates from expression trees. For hot paths, prefer direct delegates or explicit command handlers.

Benchmark your dispatch approach with representative workloads before committing to a design.

Overloads, Async Methods, And Return Handling

Real systems often have overloaded method names. Reflection lookup by name alone can select an unintended overload or fail with ambiguity. Prefer resolving methods with explicit parameter type arrays when overloads exist.

For async methods, invocation returns a Task object. You must await or synchronously observe that task result based on application model. Ignoring returned tasks hides exceptions and can make dispatch appear successful when work actually failed.

If method discovery happens repeatedly, build a startup registry mapping string keys to strongly typed delegates. This combines dynamic selection with static invocation safety and simplifies tracing. Logging selected method key, argument summary, and execution time gives useful observability for runtime dispatch paths.

Common Pitfalls

  • Invoking methods from raw user input without allow list filtering.
  • Ignoring method overload ambiguity in reflection lookup.
  • Repeating reflection lookup on every call without caching.
  • Using reflection when simple delegate maps are sufficient.
  • Skipping argument validation and getting runtime type exceptions.

Summary

  • Calling methods from strings is possible in C# via reflection or dispatch maps.
  • Reflection is flexible but slower and riskier without validation.
  • Delegate dictionaries are fast and safe for known operations.
  • Command pattern scales better for larger extensible systems.
  • Always enforce allow lists and argument validation for runtime dispatch.

Course illustration
Course illustration

All Rights Reserved.