使用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
各种Func
和Action
委托的重载(例如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传递,而不强制任何返回类型。 但它仍然有点混乱,因为你必须将一些参数传递给方法才能进行编译。