26

我在运行时使用反射进行了一些类型分析。如果我有一个 MethodInfo 实例,我如何确定这是一个“真实”方法还是一个属性的 getter/setter 方法?如果它是一个属性,我怎样才能找到它的托管 PropertyInfo 回来?

4

5 回答 5

19

好吧,getter 和 setter 背后的方法“真正的”方法。

重新跟踪到一个属性 - 模式(返回与采用 1 个参数)将有助于缩小范围 - 但您必须在每个上调用 GetGetMethod/GetSetMethod 才能找到该属性。

您可能可以尝试( Nameless 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();
    }
}
于 2009-02-06T12:47:29.263 回答
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);
}
于 2009-02-06T13:17:00.497 回答
5

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

PropertyInfo据我所知,如果不遍历属性并比较方法,就无法找到。

于 2009-02-06T12:48:45.453 回答
5

我真的很想留下这个作为评论,但我不能因为我的代表不够高:(

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);
        }
    }
于 2012-12-29T13:53:04.400 回答
-1

玩的技巧是BindingFlags.DeclaredOnlyIsSpecialName

于 2015-09-22T06:45:12.360 回答