.net reflection methodinfo propertyinfo

.net - Encontrar el alojamiento PropertyInfo del MethodInfo de getter/setter



reflection (5)

Hago algunos análisis de tipo en tiempo de ejecución usando Reflection. Si tengo una instancia de MethodInfo, ¿cómo puedo averiguar si este es un método "real" o es un método getter / setter de una propiedad? Y si es una propiedad, ¿cómo puedo encontrar de nuevo el hosting PropertyInfo?


Bueno, el método detrás de un getter y setter son métodos "reales".

Volver a rastrear a una propiedad: el patrón (return vs take 1 arg) lo ayudará a reducirlo, pero tendrá que llamar a GetGetMethod / GetSetMethod en cada uno para encontrar la propiedad.

Probablemente puedas probar el Name (menos obtener __ / set__), pero eso se siente frágil. Aquí está la versión más larga (sin uso de 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(); } }


Ecma 335 especifica (pero no exige) que los compiladores usen los prefijos get_ / set_ (capítulo 22.28). No conozco ningún idioma que rompa esa recomendación. Haciéndolo fácil:

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


El truco para jugar es BindingFlags.DeclaredOnly e IsSpecialName


Mire en MethodBase.IsSpecialName . Los métodos que no deben ser claramente visibles, como los descriptores de acceso a propiedades, los métodos de suscripción a eventos y las sobrecargas del operador, utilizan este indicador.

Que yo sepa, no hay una manera de encontrar el PropertyInfo sin iterar a través de las propiedades y comparar los métodos.


Realmente me gustaría dejar esto como un comentario, pero no puedo porque mi representante no es lo suficientemente alto :(

Hay un error en el código de Marc Gravell: si es un indexador devolverá nulo, incluso cuando exista una propiedad principal. Es bueno tener esa falla rápida, pero creo que solo podemos hacerlo cuando no tiene un valor de retorno o un parámetro:

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