J'utilise la réflexion pour charger un treeview avec la structure de classe d'un projet. Chacun des membres d'une classe se voit attribuer un attribut personnalisé.
Je n'ai aucun problème à obtenir les attributs d'une classe à l'aide de MemberInfo.GetCustomAttributes()
mais j'ai besoin d'un moyen de déterminer si un membre de la classe est une classe personnalisée et a ensuite besoin de s'analyser pour renvoyer les attributs personnalisés.
Jusqu'à présent, mon code est:
MemberInfo[] membersInfo = typeof(Project).GetProperties();
foreach (MemberInfo memberInfo in membersInfo)
{
foreach (object attribute in memberInfo.GetCustomAttributes(true))
{
// Get the custom attribute of the class and store on the treeview
if (attribute is ReportAttribute)
{
if (((ReportAttribute)attribute).FriendlyName.Length > 0)
{
treeItem.Items.Add(new TreeViewItem() { Header = ((ReportAttribute)attribute).FriendlyName });
}
}
// PROBLEM HERE : I need to work out if the object is a specific type
// and then use reflection to get the structure and attributes.
}
}
Existe-t-il un moyen simple d'obtenir le type cible d'une instance MemberInfo afin que je puisse le gérer correctement? J'ai l'impression de manquer quelque chose d'évident mais je tourne en rond à la minute.
GetProperties
renvoie un tableau de PropertyInfo
vous devez donc l'utiliser.
Il suffit alors d'utiliser la propriété PropertyType
.
PropertyInfo[] propertyInfos = typeof(Project).GetProperties();
foreach (PropertyInfo propertyInfo in propertyInfos)
{
// ...
if(propertyInfo.PropertyType == typeof(MyCustomClass))
// ...
}
Je pense que vous pouvez obtenir de meilleures performances si vous utilisez cette méthode d'extension:
public static Type GetUnderlyingType(this MemberInfo member)
{
switch (member.MemberType)
{
case MemberTypes.Event:
return ((EventInfo)member).EventHandlerType;
case MemberTypes.Field:
return ((FieldInfo)member).FieldType;
case MemberTypes.Method:
return ((MethodInfo)member).ReturnType;
case MemberTypes.Property:
return ((PropertyInfo)member).PropertyType;
default:
throw new ArgumentException
(
"Input MemberInfo must be if type EventInfo, FieldInfo, MethodInfo, or PropertyInfo"
);
}
}
Devrait fonctionner pour tout MemberInfo
, pas seulement PropertyInfo
. Vous pouvez éviter MethodInfo
de cette liste car ce n'est pas un type sous-jacent en soi (mais un type de retour).
Dans ton cas:
foreach (MemberInfo memberInfo in membersInfo)
{
foreach (object attribute in memberInfo.GetCustomAttributes(true))
{
if (attribute is ReportAttribute)
{
if (((ReportAttribute)attribute).FriendlyName.Length > 0)
{
treeItem.Items.Add(new TreeViewItem() { Header = ((ReportAttribute)attribute).FriendlyName });
}
}
//if memberInfo.GetUnderlyingType() == specificType ? proceed...
}
}
Je me demande pourquoi cela n'a pas fait partie de BCL par défaut.