varios - menu visual studio c#
¿Cómo llamar al método genérico con un objeto Tipo dado? (3)
Este enfoque no funcionará. El motivo por el que Type es un objeto cuyo tipo se determina en tiempo de ejecución. Sin embargo, está tratando de usarlo para llamar a un método genérico. El tipo de una llamada de método genérico se establece en tiempo de compilación. Por lo tanto, un objeto Type no se puede usar nunca para un parámetro de tipo en un método genérico.
Esta pregunta ya tiene una respuesta aquí:
Quiero llamar a mi método genérico con un objeto tipo dado.
void Foo(Type t)
{
MyGenericMethod<t>();
}
obviamente no funciona.
¿Cómo puedo hacer que funcione?
Necesitas usar la reflexión, desafortunadamente (por las razones que mencionó Jared). Por ejemplo:
MethodInfo method = typeof(Foo).GetMethod("MyGenericMethod");
method = method.MakeGenericMethod(t);
method.Invoke(this, new object[0]);
Obviamente, querrías comprobar más errores en la realidad :)
Nota al margen: mi MSDN local no especifica que el parámetro de MakeGenericMethod sea una matriz de parámetros, por lo que esperaba haber requerido:
method = method.MakeGenericMethod(new Type[] { t });
pero parece que es una matriz de parámetros en realidad, y los documentos en línea de MSDN están de acuerdo. Impar.
Su muestra de código no funcionará, porque el método genérico espera un identificador de tipo, no una instancia de la clase Type. Tendrás que usar el reflejo para hacerlo:
public class Example {
public void CallingTest()
{
MethodInfo method = typeof (Example).GetMethod("Test");
MethodInfo genericMethod = method.MakeGenericMethod(typeof (string));
genericMethod.Invoke(this, null);
}
public void Test<T>()
{
Console.WriteLine(typeof (T).Name);
}
}
Tenga en cuenta que esto es muy frágil, prefiero sugerir encontrar otro patrón para llamar a su método.
Otra solución hacky (tal vez alguien puede hacerlo un poco más limpio) sería usar alguna magia de expresión:
public class Example {
public void CallingTest()
{
MethodInfo method = GetMethod<Example>(x => x.Test<object>());
MethodInfo genericMethod = method.MakeGenericMethod(typeof (string));
genericMethod.Invoke(this, null);
}
public static MethodInfo GetMethod<T>(Expression<Action<T>> expr)
{
return ((MethodCallExpression) expr.Body)
.Method
.GetGenericMethodDefinition();
}
public void Test<T>()
{
Console.WriteLine(typeof (T).Name);
}
}
Observe pasar el identificador de tipo ''objeto'' como un argumento de tipo genérico en la lambda. No pude entender tan rápido cómo evitar eso. De cualquier forma, creo que esto es seguro en tiempo de compilación. Simplemente se siente mal de alguna manera: /