当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《从getter/setter的MethodInfo中查找托管PropertyInfo》经验,为你挑选了4个好方法。

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



1> Marc Gravell..:

嗯,getter和setter背后的方法 "真正的"方法.

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

你可能尝试Name(少得到__/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();
    }
}



2> Hans Passant..:

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);
}


@HansPassant:Counter-example:当MethodInfo是属性为C#显式属性实现的getter/setter时,getter和setter方法以及属性名称将以完整类型为前缀.也就是说,`object IInterface.Prop {get {return null; 在一个简单的例子中(我不知道当一个具有相同名称的属性已经存在时会发生什么),将通过私有的`IInterface.get_Prop`方法和私有的`IInterface.Prop`属性来实现.
从信息性文本来看,它必须符合CLS,但不要求是有效的IL.

3> Barry Kelly..:

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

据我所知,没有办法找到PropertyInfo没有迭代属性和比较方法.



4> Groostav..:

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

这是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);
        }
    }

推荐阅读
惬听风吟jyy_802
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有