C# 在派生泛型方法重写上查找自定义属性的干净方法(当方法为异步时)

C# 在派生泛型方法重写上查找自定义属性的干净方法(当方法为异步时),c#,inheritance,asynchronous,custom-attributes,C#,Inheritance,Asynchronous,Custom Attributes,场景: 我试图从基类中的方法检索自定义属性。这些方法是异步的 我的基类实现了包含默认逻辑的虚拟方法。具体地说,该类包装了一个EF-IRepository,并将其公开为带有/Get/Post/Delete方法的Web API。子类化此基础时的标准做法是在方法覆盖之上添加Auth属性,如[ResourceClaimsAuthorize(ResourceActions.Write,Resources.SomeResource)]。这些属性就是我想要找到的 问题: 1) 因为我在一个异步方法中,所以As

场景: 我试图从基类中的方法检索自定义属性。这些方法是异步的

我的基类实现了包含默认逻辑的虚拟方法。具体地说,该类包装了一个EF-IRepository,并将其公开为带有/Get/Post/Delete方法的Web API。子类化此基础时的标准做法是在方法覆盖之上添加Auth属性,如[ResourceClaimsAuthorize(ResourceActions.Write,Resources.SomeResource)]。这些属性就是我想要找到的

问题:

1) 因为我在一个异步方法中,所以AsyncStateMachine完成了它的工作,如果我尝试调用MethodBase.GetCurrentMethod(),我将返回“MoveNext()”,而不是实际使用的方法

2) 我尝试改用type.GetMethod(string methodName)。为了使其隐式工作,我将此方法与成功获取方法名称的[CallerMemberName]属性配对。这在一定程度上起到了作用,但在我们遇到方法重载时就中断了。如果存在重载,它不知道如何确定您想要哪个重载。这可以通过传递一个类型数组来解决,以匹配我们想要的重载的方法签名-但我真的不想通过在逻辑中包含一个类型数组来混淆我们的代码-我们正在尝试减少锅炉板,这感觉像是前进了一步,后退了两步

3) 我尝试使用一个巧妙的技巧,将
表达式
用作方法选择器。在这种方法中,我的基类调用我的Auth逻辑并传入一个lambda,该lambda“选择”了我想要的方法。比如:

apiController => apiController.Post()
然后,只需简单地抓取,就可以很容易地从MethodCallExpression中抓取该方法

expression.Body.Method; // this will be the methodinfo of the method you selected in your lambda
这几乎奏效了——但是MethodCallExpression没有选择派生类的方法,出于某种原因,表达式的类型是基类,而不是我所期望的派生类。在我的情况下,这只会导致从所选方法的基类版本中查找自定义属性;它仍然不知道该方法的派生、重写版本上的自定义属性;这正是我需要的

有更好的方法吗? 理想情况下,我希望像平常一样找到我的自定义属性,w/

var methodInfo = MethodBase.GetCurrentMethod(); 
var attributes = methodInfo.GetCustomAttributes<MyCustomAttribute>();
var methodInfo=MethodBase.GetCurrentMethod();
var attributes=methodInfo.GetCustomAttributes();
但这台机器打破了这种做法。有没有其他方法可以从异步方法内部实现这一点,同样简单?如果不是因为方法重载命名冲突,GetCurrentMethod(string methodName)w/[CallerMemberName]几乎是一个很好的修复方法,如果不是因为它获取基类方法信息而不是派生类方法信息,表达式方法选择器方法几乎可以工作


有什么想法吗?谢谢你的时间

对于任何想找和我一样东西的人,我找到了一个解决方案,使用@Jacek Gorgon的建议,在这里找到:

这允许我传入实际异步方法的方法信息,而不是异步状态机方法。Jacek提到,这不是一个很好的生产解决方案,因为它假设编译器在未来可能会发生变化。不幸的是,这是我解决问题的最好方法,而不是诉诸“在我们的api控制器中不允许方法重载”

到目前为止,一切都很好