使用Lambda表达式获取方法名称

我试图使用lambda表达式获取类型的方法名称。 我正在使用Windows Identity Foundation,需要定义具有类型名称的访问策略,其中命名空间作为资源,方法名称作为操作。 这是一个例子。

这是我将从以下类型获取类型名称和方法名称的类型:

namespace My.OrderEntry { public class Order { public void AddItem(string itemNumber, int quantity) {} } } 

这就是我想通过DSL定义访问策略的方法:

 ForResource().Performing(o => o.AddItem).AllowUsersHaving(new Claim()); 

从该声明中,我想将“My.OrderEntry.Order”作为资源,将“AddItem”作为动作。 获取带有命名空间的类型名称是没有问题的,但我认为我不能将lambda用于我正在尝试的方法。

 public static IPermissionExp Performing( this IActionExp exp, Func action) {} //this is where I don't know what to define 

这种事情甚至可能吗? 是否有另一种方法可以在不使用魔术字符串的情况下完成此类操作?

有两种方法可以做到这一点:

1:你可以进行Expression>各种FuncAction委托的重载(例如Expression> 。注意你的调用者需要在方法调用中明确指定generics参数或者通过创建委托。这将使用如下:

 ForResource().Performing(o => new Action(o.AddItem)).AllowUsersHaving(new Claim()); 

2:您可以获取包含方法调用的Expression ,并解析从表达式树中调用的MethodInfo 。 这将使用如下:

 ForResource().Performing(o => { o.AddItem(null); }).AllowUsersHaving(new Claim()); 

如果您希望将动作委托方法的名称传递给Performing函数,看起来这就是您要查找的内容。

 public static IPermissionExp Performing( this IActionExp exp, Expression> action) { var expression = action.Body as MethodCallExpression; string actionMethodName = string.Empty; if (expression != null) { actionMethodName = expression.Method.Name; } // use actionMethodName ("AddItem" in the case below) here } 

这将允许您调用这样的方法……

 ForResource().Performing((o, a, b) => o.AddItem(a, b)).AllowUsersHaving(new Claim()); 

我最近在工作中做了一件事,你使用lambda定义了一个方法,然后内部对象取名为。 你也可以使用字符串,或传入一个MethodInfo,但第一个不是真正的类型安全(错别字是一个很大的风险),而后者不是很优雅。

基本上我有一个这样的方法(这不是确切的方法,它有点更高级):

 public void SetRequest(Request req, Expression>> methodSelector); 

这里的关键是“表达式”的东西,这让你“选择”这样的方法:

 SetRequest(req, service => service.SomeMethodTakingLongReturningStuffs); 

方法选择器被制作成表达式树,然后您可以从中获取不同的数据位。 我不记得究竟是什么结果树,它还取决于你的lambda看起来如何。

您可以将其作为Action传递,而不强制任何返回类型。 但它仍然有点混乱,因为你必须将一些参数传递给方法才能进行编译。