Cómo invocar un método genérico por Type en C#: tutorial claro

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Introducción: cuando el código dice «no sé»

\n

Imagine una situación: está escribiendo una biblioteca de serialización en C#. Tiene un método Serialize<T>(T obj) que puede convertir cualquier objeto en una cadena. Todo funciona perfectamente mientras lo invoca con un tipo específico: Serialize<User>(user). Pero, ¿qué sucede si el tipo del objeto solo se conoce durante la ejecución del programa?

\n\n

Este es un problema clásico que miles de desarrolladores preguntan en Stack Overflow: «How do I call a generic method using a Type variable?». A primera vista, la solución parece simple, pero C# es un lenguaje fuertemente tipado y no se puede simplemente sustituir una variable de tipo entre los corchetes angulares.

\n\n

En este tutorial, analizaremos cómo invocar correctamente métodos genéricos mediante reflexión en C# con MakeGenericMethod. Aprenderá no solo la sintaxis, sino también cuándo es realmente necesario y cuándo es mejor buscar alternativas.

\n\n

¿Por qué no se puede simplemente escribir Method<type>()?

\n

Eliminemos las ilusiones de inmediato. El siguiente código no se compilará:

\n
Type runtimeType = someObject.GetType();\n// Error de compilación: "El tipo 'runtimeType' no es válido"\nSomeMethod<runtimeType>();\n
\n\n

¿Por qué? Porque los parámetros genéricos en C# son metadatos de tiempo de compilación. El compilador debe saber exactamente con qué tipo está trabajando para generar el código. La variable Type es un objeto que solo existe en tiempo de ejecución. Para el compilador, es simplemente una variable, no un tipo.

\n\n

La solución se encuentra en el ámbito de la reflexión: un mecanismo que permite inspeccionar e invocar miembros de tipos durante la ejecución.

\n\n

Tutorial paso a paso: invocar un método genérico mediante Type

\n

Analicemos el problema con un ejemplo concreto. Supongamos que tenemos un servicio para procesar datos:

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

Queremos invocar Process<T> cuando el tipo T solo se conoce en tiempo de ejecución, por ejemplo, desde typeof(string) o someObject.GetType().

\n\n

Paso 1. Obtener el MethodInfo para el método genérico

\n

Primero, necesitamos obtener el objeto que representa nuestro método:

\n
DataProcessor processor = new DataProcessor();\nType processorType = typeof(DataProcessor);\n\n// Buscamos el método por nombre. Importante: especificar BindingFlags si el método no es public\nMethodInfo? methodInfo = processorType.GetMethod("Process");\n
\n\n

¡Importante! Si tiene varias sobrecargas del método, deberá refinar la búsqueda usando GetMethods() y filtrando. En nuestro caso, solo hay un método, así que es simple.

\n\n

Paso 2. Convertir el método genérico en uno concreto usando MakeGenericMethod

\n

Aquí está el protagonista del artículo: el método MakeGenericMethod. Toma un arreglo de tipos y devuelve un método construido (concreto):

\n
Type runtimeType = typeof(int); // o cualquier otro tipo obtenido dinámicamente\nMethodInfo? genericMethod = methodInfo?.MakeGenericMethod(runtimeType);\n
\n\n

Ahora, genericMethod es un método completo Process<int>, listo para ser invocado.

\n\n

Paso 3. Invocar el método mediante Invoke

\n

El toque final: usar Invoke:

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

Tenga en cuenta:

\n
    \n
  • El primer parámetro de Invoke es la instancia del objeto (para métodos estáticos, null).
  • \n
  • El segundo parámetro es un arreglo de argumentos del método. Incluso si solo hay un argumento, debe estar dentro de un arreglo.
  • \n
  • El resultado se devuelve como object? — es posible que necesite convertirlo al tipo esperado.
  • \n

Blogs

Book Recommendations