En supposant la hiérarchie d'héritage hypothétique suivante:
public interface IA
{
int ID { get; set; }
}
public interface IB : IA
{
string Name { get; set; }
}
Utiliser la réflexion et faire l'appel suivant:
typeof(IB).GetProperties(BindingFlags.Public | BindingFlags.Instance)
ne donnera que les propriétés de l'interface IB
, qui est " Name
".
Si nous devions faire un test similaire sur le code suivant,
public abstract class A
{
public int ID { get; set; }
}
public class B : A
{
public string Name { get; set; }
}
l'appel typeof(B).GetProperties(BindingFlags.Public | BindingFlags.Instance)
renverra un tableau d' PropertyInfo
objets pour " ID
" et " Name
".
Existe-t-il un moyen simple de trouver toutes les propriétés dans la hiérarchie d'héritage pour les interfaces comme dans le premier exemple?
la source
Stack<Type>
au lieu d'unQueue<>
. Avec une pile, l'ascendance maintient un ordre tel queinterface IFoo : IBar, IBaz
oùIBar : IBubble
et «IBaz: IFlubber, the order of reflection becomes:
IBar,
IBubble,
IBaz,
IFlubber,
IFoo».GetProperties
. Vous utilisezGetInterfaces
sur votre type de départ qui retournera la liste aplatie de toutes les interfaces et faites simplementGetProperties
sur chaque interface. Pas besoin de récursivité. Il n'y a pas d'héritage ou de types de base dans les interfaces.Type.GetInterfaces
renvoie la hiérarchie aplatie, il n'y a donc pas besoin d'une descente récursive.La méthode entière peut être écrite de manière beaucoup plus concise en utilisant LINQ:
la source
GetValue
le récupéréPropertyInfo
, en passant votre instance (dont la valeur de propriété à obtenir) en paramètre. Exemple:var list = new[] { 'a', 'b', 'c' }; var count = typeof(IList).GetPublicProperties().First(i => i.Name == "Count").GetValue(list);
← renverra 3, même s'ilCount
est défini dansICollection
, nonIList
.GetInterfaces
n'est pas requis si letype
est une classe, car la classe concrète DOIT implémenter toutes les propriétés qui sont définies dans toutes les interfaces en aval de la chaîne d'héritage. L'utilisationGetInterfaces
dans ce scénario entraînerait la duplication de TOUTES les propriétés.Les hiérarchies d'interface sont pénibles - elles n'héritent pas vraiment en tant que telles, puisque vous pouvez avoir plusieurs «parents» (faute d'un meilleur terme).
"Aplatir" (encore une fois, pas tout à fait le bon terme) la hiérarchie peut impliquer de vérifier toutes les interfaces implémentées par l'interface et de travailler à partir de là ...
la source
Exactement le même problème a une solution de contournement décrite ici .
FlattenHierarchy ne fonctionne pas btw. (uniquement sur les variables statiques. le dit en intellisense)
Solution de contournement. Méfiez-vous des doublons.
la source
En réponse à @douglas et @ user3524983, les éléments suivants devraient répondre à la question du PO:
ou, pour une propriété individuelle:
OK la prochaine fois, je le déboguerai avant de publier au lieu après :-)
la source
cela a bien fonctionné pour moi dans un classeur de modèle MVC personnalisé. Devrait être capable d'extrapoler à n'importe quel scénario de réflexion. Encore un peu pue que c'est trop passer
la source