C# Réflexion avec la récursivité
Je suis en train de travailler sur la Réflexion , mais je suis coincé tout en faisant de la récursivité.
Code :
public class User {
public string Name;
public int Number;
public Address Address;
}
public class Address {
public string Street;
public string State;
public string Country;
}
maintenant, je suis d'impression les valeurs.
Type t = user.GetType();
PropertyInfo[] props = t.GetProperties();
foreach (PropertyInfo prp in props)
{
if(!prp.GetType().IsPrimitive && prp.GetType().IsClass)
{
//Get the values of the Inner Class.
//i am stucked over here , can anyone help me with this.
Type ty = prp.GetType();
var prpI = ty.GetProperties();
//var tp = ty.GetType().;
foreach (var propertyInfo in prpI)
{
var value = propertyInfo.GetValue(prp);
var stringValue = (value != null) ? value.ToString() : "";
console.WriteLine(prp.GetType().Name + "." + propertyInfo.Name+" Value : " +stringValue);
}
}
else
{
var value = prp.GetValue(user);
var stringValue = (value != null) ? value.ToString() : "";
console.writeline(user.GetType().Name + "." + prp.Name+" Value : " +stringValue);
}
}
je veux savoir comment faire pour savoir si la propriété est une classe ou d'une primitive. et faire la récursivité si c'est une classe.
- Pourquoi ne pas vous afficher quelque chose qui au moins compile?
- Êtes-vous sûr que la réflexion est la solution du problème? Pourquoi voulez-vous faire cela?
- Pourquoi n'essayez-vous pas Automapper il va faire le travail.
- Si vous voulez travailler de cette façon, un Dictionnaire au lieu d'une classe serait faire le travail.
- le Automapper fonctionnera sûrement, mais je veux écrire ce code sur mon propre. si quelqu'un peut m'aider comment faire pour savoir si la propriété est primitif ou de sa classe.
- Que les sons inutiles, ne pas tomber dans le "Pas inventé ici" piège...
- double possible de classes Imbriquées et récursivité
Vous devez vous connecter pour publier un commentaire.
Tout d'abord, si vous voulez accéder aux propriétés d'un type, assurez-vous d'utiliser un type qui a des propriétés:
Deuxième,
prp.GetType()
retournera toujoursPropertyInfo
. Vous êtes à la recherche pourprp.PropertyType
, qui sera de retour le Type de la propriété.Aussi,
if(!prp.GetType().IsPrimitive && prp.GetType().IsClass)
ne fonctionne pas de la manière que vous voulez, parce queString
par exemple, est une de la classe et aussi pas un primitif. Mieux utiliserprp.PropertyType.Module.ScopeName != "CommonLanguageRuntimeLibrary"
.Dernier mais non le moins, d'utiliser la récursivité, en fait, vous avez de mettre votre code dans une méthode.
Voici un exemple complet:
Utilisée comme ceci:
il sera de sortie
User
istance de la référence à uneAddress
instance qui, à son tour références de la mêmeUser
instance de nouveau.ScopeName
serait alors quelque chose commeWhateverClassLibrary.dll
"WhateverClassLibrary.dll" != "CommonLanguageRuntimeLibrary"
je ne vois pas votre problème.Tout d'abord, évitez d'utiliser la réflexion, à moins que vous vraiment besoin. C'est lent, c'est salissant, c'est limite undebuggable (et j'adore ça, mais c'est une autre chose)
Si vous voulez vider tout le contenu de votre objet, je vous recommande de transférer des objets eux-mêmes, ils doivent connaître leur état intérieur. Vous pouvez utiliser les objets
ToString
méthode pour écrire leur état intérieur, ou vous pouvez définir une interface pour l'affichage de l'état interneet vos objets en œuvre. Ensuite le code pour afficher les propriétés de l'être
Une autre option serait d'utiliser un outil comme AutoMapper qui cache la complexité et les subtilités de la réflexion à partir de vous, et expose une belle API à utiliser.
Toutefois, si vous êtes l'apprentissage de la réflexion, l'impression de l'état d'un objet complexe est un bel exercice. Quelques conseils dans ce sens:
n'est pas une propriété, il est un domaine, de sorte que
type.GetProperties()
ne la ramène pas. Lire sur ce que le C# propriétés sont, et comment ils sont utilisés et définis. Un minimum de déclaration de la propriété estAussi,
prp.GetType()
sera de retour les informations de type pour laPropertyInfo
type, pas pour le type de la propriété qu'il contient. Ce qu'il vous faut dans ce cas est leprp.PropertyType
propriété.Prochaine, je ne pense pas que le
Type.IsPrimitive
vérifier est ce que vous voulez qu'il soit. Cette propriété renvoie la valeur true pour l'Boolean, Byte, SByte, Int16, UInt16, Int32 UInt32, Int64, UInt64, IntPtr, UIntPtr, Char, Double, et un Seul des types, et false pour tout le reste. Le plus importanttypeof(string).IsPrimitive
renvoie la valeur false.Sur la même note, je ne pense pas que le
Type.IsClass
vérifier est ce que vous voulez qu'il soit, soit. Comme vous vous en servez, que seulement de vérifier si la propriété est d'une valeur ou d'un type de référence, et que les types de valeur (struct
) peut aussi être très complexes et contiennent des propriétés et domaines de leur propre, la vérification n'a pas de sens.Merci @Paresse, vous code est très utile. C'est une légère modification de ceux qui obtiennent un "Objet de référence non définie à une instance d'un objet." erreur. Il crée une instance de l'objet est null et gère également les tableaux. Plus doit être fait pour traiter tous les types de collection, mais c'est un début.
Vous pouvez utiliser le
Type.IsValueType
propriété.