Suponiendo la siguiente jerarquía de herencia hipotética:
public interface IA
{
int ID { get; set; }
}
public interface IB : IA
{
string Name { get; set; }
}
Usando la reflexión y haciendo la siguiente llamada:
typeof(IB).GetProperties(BindingFlags.Public | BindingFlags.Instance)
solo producirá las propiedades de la interfaz IB
, que es " Name
".
Si hiciéramos una prueba similar en el siguiente código,
public abstract class A
{
public int ID { get; set; }
}
public class B : A
{
public string Name { get; set; }
}
la llamada typeof(B).GetProperties(BindingFlags.Public | BindingFlags.Instance)
devolverá una matriz de PropertyInfo
objetos para " ID
" y " Name
".
¿Existe una manera fácil de encontrar todas las propiedades en la jerarquía de herencia para interfaces como en el primer ejemplo?
c#
.net
reflection
sduplooy
fuente
fuente
Stack<Type>
lugar de unQueue<>
. Con una pila, la ascendencia mantiene un orden tal queinterface IFoo : IBar, IBaz
dondeIBar : IBubble
y 'IBaz: IFlubber, the order of reflection becomes:
IBar,
IBubble,
IBaz,
IFlubber,
IFoo`.GetProperties
. UtilizaGetInterfaces
en su tipo de inicio que devolverá la lista plana de todas las interfaces y simplemente lo haráGetProperties
en cada interfaz. No hay necesidad de recursividad. No hay herencia ni tipos base en las interfaces.Type.GetInterfaces
devuelve la jerarquía aplanada, por lo que no hay necesidad de un descenso recursivo.El método completo se puede escribir de manera mucho más concisa usando LINQ:
fuente
GetValue
al recuperadoPropertyInfo
, pasando su instancia (cuyo valor de propiedad obtener) como parámetro. Ejemplo:var list = new[] { 'a', 'b', 'c' }; var count = typeof(IList).GetPublicProperties().First(i => i.Name == "Count").GetValue(list);
← devolverá 3, aunqueCount
esté definido dentroICollection
, noIList
.GetInterfaces
no es necesario sitype
es una clase, porque la clase concreta DEBE implementar todas las propiedades que están definidas en todas las interfaces a lo largo de la cadena de herencia. El usoGetInterfaces
en ese escenario daría como resultado la duplicación de TODAS las propiedades.Las jerarquías de interfaz son una molestia, en realidad no "heredan" como tales, ya que puede tener varios "padres" (a falta de un término mejor).
"Aplanar" (de nuevo, no es el término correcto) la jerarquía puede implicar la comprobación de todas las interfaces que implementa la interfaz y trabajar desde allí ...
fuente
Exactamente el mismo problema tiene una solución que se describe aquí .
FlattenHierarchy no funciona por cierto. (solo en variables estáticas. lo dice en intellisense)
Solución alterna. Tenga cuidado con los duplicados.
fuente
Respondiendo a @douglas y @ user3524983, lo siguiente debería responder a la pregunta del OP:
o, para una propiedad individual:
De acuerdo, la próxima vez lo depuraré antes de publicar en lugar de después :-)
fuente
esto funcionó muy bien y concisamente para mí en una carpeta de modelos MVC personalizada. Sin embargo, debería poder extrapolar a cualquier escenario de reflexión. Todavía apesta que es demasiado pasado
fuente