получить methodinfo из ссылки на метод C#
мы можем использовать C# typeof
ключевое слово, когда мы хотим получить экземпляр типа для указанного типа. Но что я могу использовать, если я хочу получить MethodInfo
метода по его ссылке?
например у меня есть простое консольное приложение. Он содержит Program.Main
метод. Я хочу получить MethodInfo
используя что-то вроде methodinfoof(Program.Main)
. У меня есть эта проблема, потому что имена методов могут измениться, поэтому я не могу просто использовать Type.GetMethodInfo(string MethodName)
для этого.
у меня есть около 10 000 способов, которые я хотел бы получить MethodInfo
, поэтому добавление любых пользовательских атрибутов или чего-либо еще в мои методы не является решением.
6 ответов
небольшая адаптация ранее опубликованного ответа, но это сообщение в блоге, похоже, достигает того, что вы просите; http://blog.functionalfun.net/2009/10/getting-methodinfo-of-generic-method.html
использование образца было бы следующим образом;
var methodInfo = SymbolExtensions.GetMethodInfo(() => Program.Main());
первоначальный ответ был на этот вопрос;https://stackoverflow.com/a/9132588/5827
вы можете использовать деревья выражений для нестатических методов. Вот пример.
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");
}
}
вы бы использовали его так:
MethodInfo mi = MethodInfoHelper.GetMethodInfo<Program>(x => x.Test());
Console.WriteLine(mi.Name);
Test () - функция-член, объявленная в классе программы.
использовать MemberExpression
и MemberInfo
вместо этого, если вы хотите поддерживать геттеры и сеттеры свойств.
тест класс
public class Foo
{
public void DoFoo()
{
Trace.WriteLine("DoFoo");
}
public static void DoStaticFoo()
{
Trace.WriteLine("DoStaticFoo");
}
}
и вы можете сделать что-то подобное
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
обновление
В комментарии @Greg если у вас есть некоторые параметры методов, вы можете использовать Action<T>
, Action<T1, T2>
, Action<T1, T2, T3>
или Func<T1>
, неудобство в том, что вам все равно нужно будет написать перегрузки для GetMethodInfo
.
Я знаю, что это очень старый пост, но я просто выброшу это там для кого-то, кто все еще может искать простое решение для этого.. Просто кажется, что никто не подумал о простейшем решении:
typeof(Program).GetMethods();
возвращает массив с MethodInfo всех методов в классе программы, независимо от атрибутов или наличия параметров или нет.
вы можете повторить его, если хотите, например, перечислить имена всех ваших 10.000+ методы.
вы также можете сделать typeof(Program).GetMethod(nameof(Program.Main));
таким образом, если имя метода изменить рефакторинг Visual Studio переименует его здесь тоже.
Примечание: ключевое слово "nameof" не было доступно 5 лет назад, когда был опубликован вопрос.
Я создал шаблон T4, который создает необходимые вспомогательные функции, чтобы помочь вам в этом. Он создает список функций для получения объектов MethodInfo из методов Func или Action.
скопируйте следующий код в файл с именем 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");
}
<# } #>
}
}
Примечания:
- пожалуйста, убедитесь, что Создать Действие of the .шаблон tt имеет значение нет
- вы можете создать более или менее функции путем установки переменной max в соответствующую настройку.
может быть, не идеальный способ, но это может помочь:
var callback = typeof(BlogController).GetMethod(nameof(BlogController.GetBlogs));