从策略注入中判断方法是否是属性的最佳方法是什么?

时间: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几乎可以满足所有需求。