.net 从getter/setter的MethodInfo中查找宿主PropertyInfo

km0tfn4u  于 2023-01-27  发布在  .NET
关注(0)|答案(6)|浏览(120)

我在运行时使用Reflection做一些类型分析。如果我有一个MethodInfo示例,我如何判断这是一个“真实的的”方法还是一个属性的getter/setter方法?如果它是一个属性,我如何找到它的宿主PropertyInfo?

2o7dmzc5

2o7dmzc51#

好吧,getter和setter后面的方法是“真实的的”方法。
重新跟踪到属性-模式(return vs take 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();
    }
}
3pmvbmvn

3pmvbmvn2#

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

djmepvbi3#

研究一下MethodBase.IsSpecialName,那些不应该明显可见的方法,比如属性访问器,事件订阅方法和运算符重载都使用这个标志。
据我所知,如果不迭代属性并比较方法,就无法找到PropertyInfo

5t7ly7z5

5t7ly7z54#

我真的很想把这个作为一个评论,但我不能,因为我的代表是不够高:
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);
        }
    }
bksxznpy

bksxznpy5#

对于今天的.NET,我相信下面的答案与Marc的答案相同,但更简洁,可能更有效。

public static PropertyInfo? GetPropertyInfo(this MethodInfo getSetMethodInfo) 
    => getSetMethodInfo.DeclaringType?.GetProperties()
    .FirstOrDefault(prop => prop.GetSetMethod() == getSetMethodInfo 
    || prop.GetGetMethod() == getSetMethodInfo);
4xy9mtcn

4xy9mtcn6#

要使用的技巧是BindingFlags.DeclaredOnlyIsSpecialName

相关问题