Meilleure façon d'obtenir des sous-propriétés à l'aide de GetProperty
public class Address
{
public string ZipCode {get; set;}
}
public class Customer
{
public Address Address {get; set;}
}
comment puis-je accéder à eitther "code Postal" ou "Adresse.Code postal" avec la réflexion? Par exemple:
Typeof(Customer).GetProperty("ZipCode")?
Vous devez vous connecter pour publier un commentaire.
Vous auriez besoin de quelque chose comme:
Fondamentalement, si vous voulez prendre une corde "de l'Adresse.Code postal" et naviguez vers le bas, vous devez diviser par "." et ensuite appeler GetProperty sur le type approprié à chaque étape pour obtenir la propriété elle-même, puis PropertyInfo.GetValue pour obtenir la valeur suivante dans la chaîne. Quelque chose comme ceci:
L'appeler comme ceci:
Notez que cela fonctionne sur le moment de la compilation types de propriétés. Si vous le souhaitez pour faire face au temps d'exécution de type (par exemple, si le client.L'adresse n'a pas un code Postal de la propriété, mais le type retourné par Adresse) puis changer
property.PropertyType
àproperty.GetType()
.Notez également que ce n'est pas toute erreur de manipulation etc 🙂
Jon Skeet la réponse est bien, j'ai dû prolonger sa méthode un peu cependant, afin de tenir compte des dérivés des instances dans le chemin de la propriété:
L'aide de la propriété.PropertyType permettra d'obtenir le type de propriété définie sur l'obj classe, tout en utilisant obj.GetType() vous obtiendrez le type réel de la propriété de l'instance.
EDIT: @Oliver - vous avez tout à fait raison, merci de noter que. J'ai ajusté la méthode pour permettre générique Listes et les Dictionnaires. Bien que je n'aime pas l'analyse de la partie, j'ai utilisé Marc Gravel de l'idée astucieuse dans ce fil pour obtenir l'indexeur valeurs du bien.
somePerson.Adresses[3].Street
)Les questions /réponses sont beaux; juste un point de vue alternatif: dans de nombreux cas, il est souhaitable d'utiliser le Système.ComponentModel plutôt que de la réflexion, car cela permet d'exécution propriété scénarios - à-dire comment un DataTable du DataView expose les colonnes comme propriétés.
Performance sage - par défaut, c'est en grande partie identique, mais si vous faites beaucoup de ce (par exemple, la masse de données importation/exportation), vous pouvez réellement obtenir une amélioration significative des performances à l'aide de cette approche, avec l'aimable autorisation de HyperDescriptor.
À utiliser le Système.ComponentModel, le code est similaire, mais légèrement différents:
Cela vous donne ensuite la même manipulation que si vous aviez utilisé les données de liaison pour lier à "Adresse.Code postal" (abstraction de certains détails comme les listes, etc).
(à noter que vous pourriez lancer zip comme une chaîne de caractères, etc si vous savez qui est le type attendu)
Pour obtenir la valeur d'un profond chemin d'accès (y compris la même liste de manipulation de liaison de données utilise), vous pouvez utiliser quelque chose comme:
La liste des trucs environ reflète le comportement de l'ordinaire de liaison de données (bien qu'il omet de mentionner quelques petites choses comme la liaison des contextes de devises, gestionnaires, etc)
adabyron,
J'ai créé une version de votre code quand vous avez seulement besoin de saisir les types, et si vous n'avez pas une réelle instance de l'objet.
Problème: Faiblement Typé Variables:
@jonskeet de FollowPropertyPath(...) la méthode presque répondu à mes besoins exactement, sauf que,
ma propriété est faiblement typé; par conséquent,
currentType = property.PropertyType
simplement retourné Système.Objet et échoué sur la prochaine itération de la boucle foreach boucle.Solution:
Pour utiliser le moteur d'exécution de type plutôt que le moment de la conception de type, j'ai ajusté la méthode comme suit: