es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

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&lt;Tf&gt;() 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.

Tags:  , , , ,

Answer

  1. Avatar for 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 con MakeGenericMethod.

    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.

Comments are closed.