How to Call a Generic Method by Type in C#: A Clear Tutorial

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: When the Code Says "I Don't Know"

\n

Imagine a scenario: you are writing a serialization library in C#. You have a method Serialize<T>(T obj) that can turn any object into a string. Everything is fine as long as you call it with a specific type: Serialize<User>(user). But what do you do if the type of the object becomes known only at runtime?

\n\n

This is a classic problem asked by thousands of developers on Stack Overflow: "How do I call a generic method using a Type variable?". At first glance, the solution seems simple, but C# is a strongly typed language, and you cannot simply substitute a type variable into angle brackets.

\n\n

In this tutorial, we will break down how to correctly call generic methods using C# reflection with MakeGenericMethod. You will learn not only the syntax but also when it is truly necessary and when it is better to look for alternatives.

\n\n

Why Can't You Just Write Method<type>()?

\n

Let's dispel any illusions right away. The following code will not compile:

\n
Type runtimeType = someObject.GetType();\n// Compilation error: "'runtimeType' is a variable but is used like a type"\nSomeMethod<runtimeType>();\n
\n\n

Why? Because generic parameters in C# are compile-time metadata. The compiler must know exactly which type it is working with to generate code. A Type variable is an object that exists only at runtime. To the compiler, it is just a variable, not a type.

\n\n

The solution lies in reflection — a mechanism that allows you to inspect and invoke type members at runtime.

\n\n

Step-by-Step Tutorial: Calling a Generic Method via Type

\n

Let's break down the task with a concrete example. Suppose we have a service for processing data:

\n
public class DataProcessor\n{\n    public string Process<T>(T data)\n    {\n        return $"Processed {typeof(T).Name}: {data}";\n    }\n}\n
\n\n

We want to call Process<T> when the type T is known only at runtime, for example, from typeof(string) or someObject.GetType().

\n\n

Step 1. Get the MethodInfo for the Generic Method

\n

First, we need to get the object representing our method:

\n
DataProcessor processor = new DataProcessor();\nType processorType = typeof(DataProcessor);\n\n// Find the method by name. Important: specify BindingFlags if the method is not public\nMethodInfo? methodInfo = processorType.GetMethod("Process");\n
\n\n

Important! If you have multiple method overloads, you will need to refine the search using GetMethods() and filtering. In our case, there is only one method — it's simple.

\n\n

Step 2. Turn the Generic Method into a Concrete One Using MakeGenericMethod

\n

Here it is, the main character of the article — the MakeGenericMethod method. It takes an array of types and returns a constructed (concrete) method:

\n
Type runtimeType = typeof(int); // or any other type obtained dynamically\nMethodInfo? genericMethod = methodInfo?.MakeGenericMethod(runtimeType);\n
\n\n

Now genericMethod is a fully-fledged method Process<int>, ready to be called.

\n\n

Step 3. Call the Method via Invoke

\n

The final step — using Invoke:

\n
object? result = genericMethod?.Invoke(processor, new object[] { 42 });\nConsole.WriteLine(result); // Outputs: "Processed Int32: 42"\n
\n\n

Note:

\n
    \n
  • The first parameter of Invoke is the object instance (for static methods — null).
  • \n
  • The second parameter is an array of method arguments. Even if there is only one argument, it must be in an array.
  • \n
  • The result is returned as object? — you may like

Blogs

Book Recommendations