从策略注入中判断方法是否是属性的最佳方法是什么?
时间:2020-03-05 18:56:15 来源:igfitidea点击:
我已经将一个自定义处理程序应用于一个类(使用entlib 4中的Policy Injection Application Block),我想知道在调用Invoke时输入法是否是属性。以下是我的处理程序的外观。
[ConfigurationElementType(typeof(MyCustomHandlerData))] public class MyCustomHandler : ICallHandler { public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext) { if (input.MethodBase.IsPublic && (input.MethodBase.Name.Contains("get_") || input.MethodBase.Name.Contains("set_"))) { Console.WriteLine("MyCustomHandler Invoke called with input of {0}", input.MethodBase.Name); } return getNext().Invoke(input, getNext); } public int Order { get; set; } }
从我的代码示例中可以看到,到目前为止,我想到的最好的方法是解析方法名称。有没有更好的方法可以做到这一点?
解决方案
回答
我们可以检查IsSpecialName属性;对于属性获取器和设置器而言,这将是正确的。但是,对于其他特殊方法,例如运算符重载,也是如此。
回答
我不熟悉该应用程序块,但是假设MethodBase属性的类型为System.Reflection.MethodBase,则可以看一下IsSpecialName属性。
MSDN上的System.Reflection.MethodBase.IsSpecialName
回答
我们还可以检查IsSpecialName为true。这在房地产中将是正确的(除其他事项外)
在il级别,方法公开如下(以Environment.ExitCode为例):
.method public hidebysig specialname static int32 get_ExitCode() cil managed .method public hidebysig specialname static void set_ExitCode(int32 'value') cil managed
如果我们想花哨的话,可以在提取出该属性存在的名称后进行验证,说实话
if (m.IsSpecialName && (m.Attributes & MethodAttributes.HideBySig) != 0))
以及以get_或者set_开头,那么即使对于使用讨厌名称的人也应该很好(伪造hidebysig很容易,伪造IsSpecialName会非常棘手)
虽然没有任何保证。有人可以使用set_Foo方法发出一个类,该类看起来像一个真正的set方法,但实际上不是只读属性上的集合。
除非我们检查属性是否也可以读取/可以写入。
尽管我们并不期望故意进行绕行,但这使我为我们感到疯狂。
在MethodInfo上执行此逻辑的简单实用程序/扩展方法并不难,包括IsSpecialName几乎可以满足所有需求。