从方法引用C#获取methodinfo
当我们想要获取指定类型的Type实例时,我们可以使用C# typeof
关键字。 但是,如果我想通过它的引用获取方法的MethodInfo
,我可以使用什么?
例如,我有一个简单的控制台应用程序。 它包含Program.Main
方法。 我想通过使用methodinfoof(Program.Main)
类的东西获得MethodInfo
。 我有这个问题,因为方法名称可能会更改,所以我不能只使用Type.GetMethodInfo(string MethodName)
。
我有大约10000个方法,我想获得MethodInfo
,所以在我的方法中添加任何自定义属性或其他任何东西都不是解决方案。
轻微改编以前发布的答案,但这篇博文似乎达到了你的要求; 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(Expression> 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(x => x.Test()); Console.WriteLine(mi.Name);
Test()是在Program类中声明的成员函数。
如果要支持属性getter和setter,请使用MemberExpression
和MemberInfo
。
考试class
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
, Action
, Action
或Func
,不便之处是你仍然会需要为GetMethodInfo
编写重载。
我知道这是一个非常古老的post,但我会把它扔给那些可能仍在寻找一个简单解决方案的人。这似乎没有人想到最简单的解决方案:
typeof(Program).GetMethods();
返回一个数组,其中包含Program类中所有方法的MethodInfo,无论属性如何或是否具有参数。
例如,您可以根据需要迭代它,以列出所有10.000+方法的名称。
你也可以做typeof(Program).GetMethod(nameof(Program.Main));
这样,如果方法的名称改变,Visual Studio的重构也会在这里重命名。
注意:5年前发布问题时,“nameof”关键字不可用。
我创建了一个T4模板,可以创建所需的帮助函数来帮助您完成此任务。 它创建了一个函数列表,用于从Func <>或Action <>方法获取MethodInfo对象。
将以下代码复制到名为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>(Expression>> 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>> expression) { var member = expression.Body as MethodCallExpression; if (member != null) return member.Method; throw new ArgumentException("Expression is not a method", "expression"); } <# } #> } }
备注 :
- 请确保.tt模板的Build Action设置为None
- 您可以通过将max变量设置为适当的设置来创建更多或更少的function。
也许不是理想的方式,但它可以帮助:
var callback = typeof(BlogController).GetMethod(nameof(BlogController.GetBlogs));