从getter / setter的MethodInfo中查找托管PropertyInfo

时间:2009-02-06 12:39:44

标签: .net reflection methodinfo propertyinfo

我在运行时使用Reflection进行一些类型分析。如果我有一个MethodInfo实例, 我怎么能弄清楚这是一个“真正的”方法还是属性的getter / setter方法?如果它是一个属性,我怎样才能找到它的托管PropertyInfo?

5 个答案:

答案 0 :(得分:17)

嗯,getter和setter 背后的方法是“真正的”方法。

重新追溯到一个属性 - 模式(返回vs取1 arg)将有助于缩小它 - 但你必须在每个上调用GetGetMethod / GetSetMethod才能找到属性。

你可以可能尝试Name(减去get __ / set__) - 但这感觉很脆弱。这是较长的版本(不使用Name):

static PropertyInfo GetProperty(MethodInfo method)
{
    bool takesArg = method.GetParameters().Length == 1;
    bool hasReturn = method.ReturnType != typeof(void);
    if (takesArg == hasReturn) return null;
    if (takesArg)
    {
        return method.DeclaringType.GetProperties()
            .Where(prop => prop.GetSetMethod() == method).FirstOrDefault();
    }
    else
    {
        return method.DeclaringType.GetProperties()
            .Where(prop => prop.GetGetMethod() == method).FirstOrDefault();
    }
}

答案 1 :(得分:7)

Ecma 335指定(但不要求)编译器使用get_ / set_前缀(第22.28章)。我不知道任何违反该建议的语言。轻松一点:

public static PropertyInfo GetPropFromMethod(Type t, MethodInfo method) {
  if (!method.IsSpecialName) return null;
  return t.GetProperty(method.Name.Substring(4), 
    BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic);
}

答案 2 :(得分:5)

查看MethodBase.IsSpecialName。不应该明显可见的方法,例如属性访问器,事件订阅方法和操作符重载使用此标志。

据我所知,没有办法找到PropertyInfo而没有迭代属性并比较方法。

答案 3 :(得分:5)

我真的想留下这个评论作为评论,但由于我的代表不够高,我不能这样做:(

Thec是Marc Gravell代码中的一个错误:如果它是一个索引器,它将返回null,即使父属性存在也是如此。很高兴有快速失败,但我认为我们只能在没有返回值或参数的情况下这样做:

    [Pure]
    public static PropertyInfo GetParentProperty(this MethodInfo method)
    {
        if (method == null) throw new ArgumentNullException("method");
        var takesArg = method.GetParameters().Length == 1;
        var hasReturn = method.ReturnType != typeof(void);
        if (!(takesArg || hasReturn)) return null;

        if (takesArg && !hasReturn)
        {
            return method.DeclaringType.GetProperties().FirstOrDefault(prop => prop.GetSetMethod() == method);
        }
        else
        {
            return method.DeclaringType.GetProperties().FirstOrDefault(prop => prop.GetGetMethod() == method);
        }
    }

答案 4 :(得分:-1)

使用的技巧是 BindingFlags.DeclaredOnly IsSpecialName