Modèle f # correspondant aux types
Je suis en train de récursivement imprimer tous une propriétés des objets et les sous-propriétés de type de etc. Mon modèle d'objet est comme suit...
type suggestedFooWidget = {
value: float ;
hasIncreasedSinceLastPeriod: bool ;
}
type firmIdentifier = {
firmId: int ;
firmName: string ;
}
type authorIdentifier = {
authorId: int ;
authorName: string ;
firm: firmIdentifier ;
}
type denormalizedSuggestedFooWidgets = {
id: int ;
ticker: string ;
direction: string ;
author: authorIdentifier ;
totalAbsoluteWidget: suggestedFooWidget ;
totalSectorWidget: suggestedFooWidget ;
totalExchangeWidget: suggestedFooWidget ;
todaysAbsoluteWidget: suggestedFooWidget ;
msdAbsoluteWidget: suggestedFooWidget ;
msdSectorWidget: suggestedFooWidget ;
msdExchangeWidget: suggestedFooWidget ;
}
Et mon récursivité est basé sur le filtrage suivant...
let rec printObj (o : obj) (sb : StringBuilder) (depth : int)
let props = o.GetType().GetProperties()
let enumer = props.GetEnumerator()
while enumer.MoveNext() do
let currObj = (enumer.Current : obj)
ignore <|
match currObj with
| :? string as s -> sb.Append(s.ToString())
| :? bool as c -> sb.Append(c.ToString())
| :? int as i -> sb.Append(i.ToString())
| :? float as i -> sb.Append(i.ToString())
| _ -> printObj currObj sb (depth + 1)
sb
Dans le débogueur je vois que currObj est de type string, int, float, etc, mais il saute toujours defualt affaire au fond. Une idée de pourquoi ce qui se passe?
source d'informationauteur PhilBrown
Vous devez vous connecter pour publier un commentaire.
Comme d'autres l'ont souligné, vous avez besoin d'invoquer la
GetValue
membre pour obtenir la valeur de la propriété - l'itération que vous avez mis en œuvre itère surPropertyInfo
objets, qui sont des "descripteurs de la propriété" - et non pas des valeurs réelles. Cependant, je n'arrive pas à comprendre pourquoi êtes-vous à l'aide deGetEnumerator
etwhile
boucle explicitement lorsque la même chose peut être écrite à l'aide defor
boucle.Aussi, vous n'avez pas besoin d'ignorer la valeur retournée par la
sb.Append
d'appel vous pouvez renvoyer simplement comme le résultat d'ensemble (parce que c'est laStringBuilder
). Ce sera effectivement rendre le code plus efficace (parce qu'il permet à la queue-appel optimizataion). Comme un dernier point, vous n'avez pas besoinToString
danssb.Append(..)
parce que leAppend
méthode est surchargée et fonctionne pour tous les types standard.Donc après un peu de simplification, vous pouvez obtenir quelque chose comme ceci (ce n'est pas vraiment à l'aide de la
depth
paramètre, mais je suppose que vous voulez l'utiliser pour quelque chose plus tard):Voici comment je l'ai eu à travailler...
Dans votre exemple,
enumer.Current
est un objet contenant une PropertyInfo. Cela signifie que currObj est toujours un PropertyInfo objet, et correspond toujours à la dernière affaire dans votre déclaration.Puisque vous êtes intéressés par le type de la valeur de la propriété, vous aurez besoin d'appeler le GetValue() la méthode de la PropertyInfo pour obtenir la valeur réelle de la propriété (comme dans ChaosPandion de réponse).
Depuis un Énumérateur renvoie ses valeurs en tant qu'objets, vous aurez également besoin de jeter l'enum.le courant pour une PropertyInfo avant de pouvoir accéder à GetValue.
Essayez de remplacer
avec
Avec ce changement, je peux obtenir votre code de travail (FSI):
Êtes-vous sûr que le programme ne se comporte pas comme prévu? Le débogueur s'étend sur ne sont pas toujours fiables.
Vous voulez quelque chose comme cela à la place.
Ce qui est à venir à partir de MSDN docs sur le
Array
classe: