确定MethodInfo实例是否是属性访问器

Pau*_*ane 11 c# reflection

我正在使用Castle DynamicProxy编写装饰代理.我需要代理的拦截器来拦截属性写入(而不是读取)所以我正在检查方法的名称:

public void Intercept(IInvocation invocation)
{
    if (invocation.Method.Name.StartsWith("set_")
    {
        // ...
    }

    invocation.Proceed();
}
Run Code Online (Sandbox Code Playgroud)

现在这个工作正常,但我不喜欢我的代理人对如何实现属性有深入了解的事实:我想用类似于以下内容的方法替换方法名称检查:

if (invocation.Method.IsPropertySetAccessor)
Run Code Online (Sandbox Code Playgroud)

不幸的是,我的Google-fu失败了.有任何想法吗?

Hei*_*nzi 17

您可以检查是否存在此方法为setter(未测试)的属性:

bool isSetAccessor = invocation.Method.DeclaringType.GetProperties() 
        .Any(prop => prop.GetSetMethod() == invocation.Method)
Run Code Online (Sandbox Code Playgroud)

(从Marc对相关问题的回答中得到的启示.)

  • 看起来非常有用 (2认同)

Mar*_*ell 5

我没有意识到任何伏都教.或许,您可以剥离set_,查找具有该名称的属性,并将MethodInfoinstance(invocation.Method)与属性accessor(GetSetMethod())进行比较 - 但是,我不能诚实地说(不检查)是否会获得相同的MethodInfo实例(甚至如果它相同的方法).

if(method.IsSpecialName && method.Name.StartsWith("set_"))
{
    var prop = typeof (Foo).GetProperty(method.Name.Substring(4),
           BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
    var accessor = prop.GetSetMethod();
    bool isSame = accessor == method;
}
Run Code Online (Sandbox Code Playgroud)