Defina un lambda genérico en C# y asígnele una variable para ser usada con MakeGenericMethod.
Sé que puedo definir una función genérica y luego llamarla con parámetros de tipo usando la reflexión. Algo así:
private static void SomeFunc<Tf>()
{
// Algo seguro de tipo contra Tf
}
public void CallingFunc()
{
var someType = typeof(whatever); // Esto también se puede recuperar mediante reflexión en su lugar
var someMethod = this.GetType().GetMethod(nameof(SomeFunc)), BindingFlags.Static | BindingFlags.NonPublic);
var typedMethod = someMethod.MakeGenericMethod(someType);
typedMethod.Invoke(null, null);
}
Ahora, ¿hay alguna manera de declarar esta función SomeMethod<Tf>()
en línea como una lambda, para evitar declararla como un método separado en la clase, pero aún así poder usarla con MakeGenericMethod
? Algo así:
public void CallingFunc()
{
var someType = typeof(whatever); // Esto también se puede recuperar mediante reflexión en su lugar
// Obviamente, esto no funciona ya que requiere que Tf se conozca en esta etapa, y solo podemos tener Tf como una variable de tipo aquí => ¿qué debería hacer en su lugar?
var someMethod = new Action<Tf>(() => /* Algo seguro de tipo contra Tf */).Method;
var typedMethod = someMethod.MakeGenericMethod(someType);
typedMethod.Invoke(null, null);
}
Hacer que CallingFunc
sea genérico tampoco es una opción: la variable someType
se recupera mediante reflexión, por lo que no se conoce en tiempo de compilación.
davy.ai
Desafortunadamente, no es posible declarar una función genérica en línea como una expresión lambda y seguir usándola con
MakeGenericMethod
a través de reflexión. Esto se debe a que las expresiones lambda se compilan en tipos de delegado en tiempo de ejecución, y estos tipos de delegado no se pueden utilizar directamente conMakeGenericMethod
.Una posible solución es utilizar árboles de expresión en lugar de expresiones lambda. Los árboles de expresión le permiten construir una expresión lambda dinámicamente en tiempo de ejecución, y luego compilarla en un tipo de delegado que se puede utilizar con
MakeGenericMethod
. Sin embargo, este enfoque puede ser más complicado y detallado que simplemente declarar un método genérico separado.Otra opción es utilizar una biblioteca de generación de código como Roslyn para generar el método genérico necesario en tiempo de ejecución, basado en el parámetro de tipo deseado. Esta puede ser una solución más flexible y poderosa, pero requiere más conocimiento de las técnicas y herramientas de generación de código.