c# - español - que es set en programacion
obtener methodinfo de un método de referencia C# (6)
Tal vez no de la manera ideal, pero podría ayudar:
var callback = typeof(BlogController).GetMethod(nameof(BlogController.GetBlogs));
Podemos utilizar un tipo de palabra clave C # cuando queremos obtener la instancia de Tipo para el tipo especificado. Pero, ¿qué puedo usar si quiero obtener MethodInfo
de un método por su referencia?
Por ejemplo, tengo una aplicación de consola simple. Contiene el método Program.Main
. Quiero obtener MethodInfo
utilizando algo como methodinfoof(Program.Main)
. Tengo este problema porque los nombres de los métodos pueden cambiar, así que no puedo usar Type.GetMethodInfo(string MethodName)
para eso.
Tengo alrededor de 10 000 métodos para los cuales me gustaría obtener MethodInfo
, por lo que agregar cualquier atributo personalizado o cualquier otra cosa a mis métodos no es una solución.
Clase de prueba
public class Foo
{
public void DoFoo()
{
Trace.WriteLine("DoFoo");
}
public static void DoStaticFoo()
{
Trace.WriteLine("DoStaticFoo");
}
}
Y puedes hacer algo como esto
MethodInfo GetMethodInfo(Action a)
{
return a.Method;
}
var foo = new Foo();
MethodInfo mi = GetMethodInfo(foo.DoFoo);
MethodInfo miStatic = GetMethodInfo(Foo.DoStaticFoo);
//do whatever you need with method info
Actualizar
Por @Greg comentario si tiene algunos parámetros para los métodos, puede usar Action<T>
, Action<T1, T2>
, Action<T1, T2, T3>
, o Func<T1>
, la inconveniencia es que todavía necesita escribir las sobrecargas para GetMethodInfo
.
Puede usar árboles de expresiones para métodos no estáticos. Aquí hay un ejemplo.
using System.Linq.Expressions;
using System.Reflection;
public static class MethodInfoHelper
{
public static MethodInfo GetMethodInfo<T>(Expression<Action<T>> expression)
{
var member = expression.Body as MethodCallExpression;
if (member != null)
return member.Method;
throw new ArgumentException("Expression is not a method", "expression");
}
}
Lo usarías así:
MethodInfo mi = MethodInfoHelper.GetMethodInfo<Program>(x => x.Test());
Console.WriteLine(mi.Name);
Test () es una función miembro declarada en la clase Program.
Use MemberExpression
y MemberInfo
en su lugar si desea admitir getters y setters de propiedades.
Creé una plantilla T4 que crea las funciones auxiliares necesarias para ayudarte con esto. Crea una lista de funciones para obtener objetos MethodInfo de los métodos Func <> o Action <>.
Copie el siguiente código en un archivo llamado GetMethodInfo.tt
:
<#@ template language="C#" #>
<#@ output extension=".cs" encoding="utf-8" #>
<#@ import namespace="System" #>
<#@ import namespace="System.Text" #>
using System;
using System.Linq.Expressions;
using System.Reflection;
namespace Tools
{
public static class GetMethodInfo
{
<# int max = 12;
for(int i = 0; i <= max; i++)
{
var builder = new StringBuilder();
for(int j = 0; j <= i; j++)
{
builder.Append("T");
builder.Append(j);
if(j != i)
{
builder.Append(", ");
}
}
var T = builder.ToString();
#>
public static MethodInfo ForFunc<T, <#= T #>>(Expression<Func<T, <#= T #>>> expression)
{
var member = expression.Body as MethodCallExpression;
if (member != null)
return member.Method;
throw new ArgumentException("Expression is not a method", "expression");
}
public static MethodInfo ForAction<<#= T #>>(Expression<Action<<#= T #>>> expression)
{
var member = expression.Body as MethodCallExpression;
if (member != null)
return member.Method;
throw new ArgumentException("Expression is not a method", "expression");
}
<# } #>
}
}
Notas :
- asegúrese de que la acción de compilación de la plantilla .tt esté configurada en Ninguno
- puede crear más o menos funciones estableciendo la variable máxima en la configuración adecuada.
Sé que esta es una publicación muy antigua, pero voy a presentar esto para alguien que todavía esté buscando una solución simple para esto ... Parece que nadie pensó en la solución más simple:
typeof(Program).GetMethods();
Devuelve una matriz con MethodInfo de todos los métodos en la clase Program, independientemente de los atributos o de tener parámetros o no.
Puede repetirlo si lo desea, por ejemplo, para enumerar los nombres de todos sus más de 10.000 métodos.
También puede hacer typeof(Program).GetMethod(nameof(Program.Main));
De esta forma, si cambia el nombre del método, la refacturación de Visual Studio también lo cambiará de nombre.
NOTA: La palabra clave "nombre de" no estaba disponible hace 5 años cuando se publicó la pregunta.
Adaptación leve de una respuesta publicada anteriormente, pero esta publicación de blog parece lograr lo que estás pidiendo; http://blog.functionalfun.net/2009/10/getting-methodinfo-of-generic-method.html
El uso de la muestra sería el siguiente;
var methodInfo = SymbolExtensions.GetMethodInfo(() => Program.Main());
La respuesta original fue a esta pregunta; https://.com/a/9132588/5827