通过get或set方法的MethodInfo获得相应的PropertyInfo的方式

在IronPython 46307的MemberExpression.cs里,可以看到DLR是如何获取一个get或者set方法对应的属性的PropertyInfo的:
/// <summary>
/// Creates a <see cref="MemberExpression"/> accessing a property.
/// </summary>
/// <param name="expression">The containing object of the property.  This can be null for static properties.</param>
/// <param name="propertyAccessor">An accessor method of the property to be accessed.</param>
/// <returns>The created <see cref="MemberExpression"/>.</returns>
public static MemberExpression Property(Expression expression, MethodInfo propertyAccessor) {
    ContractUtils.RequiresNotNull(propertyAccessor, "propertyAccessor");
    ValidateMethodInfo(propertyAccessor);
    return Property(expression, GetProperty(propertyAccessor));
}

private static PropertyInfo GetProperty(MethodInfo mi) {
    Type type = mi.DeclaringType;
    BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic;
    flags |= (mi.IsStatic) ? BindingFlags.Static : BindingFlags.Instance;
    PropertyInfo[] props = type.GetProperties(flags);
    foreach (PropertyInfo pi in props) {
        if (pi.CanRead && CheckMethod(mi, pi.GetGetMethod(true))) {
            return pi;
        }
        if (pi.CanWrite && CheckMethod(mi, pi.GetSetMethod(true))) {
            return pi;
        }
    }
    throw Error.MethodNotPropertyAccessor(mi.DeclaringType, mi.Name);
}

private static bool CheckMethod(MethodInfo method, MethodInfo propertyMethod) {
    if (method == propertyMethod) {
        return true;
    }
    // If the type is an interface then the handle for the method got by the compiler will not be the 
    // same as that returned by reflection.
    // Check for this condition and try and get the method from reflection.
    Type type = method.DeclaringType;
    if (type.IsInterface && method.Name == propertyMethod.Name && type.GetMethod(method.Name) == propertyMethod) {
        return true;
    }
    return false;
}

这代码太丑了,居然要自己遍历类型的所有属性,线性的一个个找 = =
.NET Framework的标准库怎么就不提供标准的方法来查询一个方法是否是某个属性的get或者set方法呢,属性明明不只是C#的概念,也是CLI的概念啊。看来类似的功能得加到自己的utils里去,不然每次都这么搞太麻烦了。

DLR里有很多扩展方法都值得借鉴,因为光靠.NET标准库提供的方法很多时候还是会重复不少代码的。像是一些对数组的扩展方法就挺不错的。

你可能感兴趣的:(C++,c,.net,C#)