我有一个应用于类的自定义处理程序(使用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; }
}
从我的代码示例中可以看出,到目前为止我想到的最好方法是解析方法名称。有没有更好的方法来做到这一点?
答案 0 :(得分:4)
您还可以检查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方法,但实际上并不是只读属性的一个集合。 除非您检查属性CanRead / CanWrite是否也是。
虽然你并不期待故意的规避,但这让我感到很疯狂。 MethodInfo上的一个简单的实用程序/扩展方法,它执行此逻辑并不会太难,包括IsSpecialName几乎肯定会满足您的所有需求。
答案 1 :(得分:0)
您可以检查IsSpecialName属性;财产获取者和制定者都是如此。但是,对于其他特殊方法也是如此,例如运算符重载。
答案 2 :(得分:0)
我不熟悉该应用程序块,但假设MethodBase属性的类型为System.Reflection.MethodBase,您可以查看IsSpecialName属性。
答案 3 :(得分:0)
有几个人提到过使用MethodBase类型的“IsSpecialName”属性。虽然对于属性“gets”或“sets”,它将返回true,但对于运算符重载(例如add_EventName或remove_EventName),它也将返回true。因此,您需要检查MethodBase实例的其他属性,以确定它是否为属性访问器。不幸的是,如果您拥有的只是对MethodBase实例的引用(我认为是Unity框架中拦截行为的情况),那么确定它是属性setter还是getter并不是真正的“干净”方法。我发现的最好方法如下:
C#:
bool IsPropertySetter(MethodBase methodBase){
return methodBase.IsSpecialName && methodBase.Name.StartsWith("set_");
}
bool IsPropertyGetter(MethodBase methodBase){
return methodBase.IsSpecialName && methodBase.Name.StartsWith("get_");
}
VB:
Private Function IsPropertySetter(methodBase As MethodBase) As Boolean
Return methodBase.IsSpecialName AndAlso methodBase.Name.StartsWith("set_")
End Function
Private Function IsPropertyGetter(methodBase As MethodBase) As Boolean
Return methodBase.IsSpecialName AndAlso methodBase.Name.StartsWith("get_")
End Function
答案 4 :(得分:0)
有点晚了,但其他人也会读到这个。除了IsSpecialName并检查set_前缀(运算符有op_,事件subscr./remov。有add_,remove_),您可以检查方法是否与任何属性方法匹配,如下所示:
bool isProperty = method.ReflectedType.GetProperties().FirstOrDefault(p =>
p.GetGetMethod().GetHashCode() == method.GetHashCode()
|| p.GetSetMethod().GetHashCode() == method.GetHashCode())!=null;