web-dev-qa-db-fra.com

Existe-t-il un moyen simple de convertir les propriétés d’un objet en dictionnaire <string, string>

J'ai un objet de base de données (une ligne), qui a beaucoup de propriétés (colonnes) qui correspondent aux champs de formulaire (asp: zone de texte, asp: liste déroulante, etc.) . Je souhaite transformer cet objet et ces propriétés en une carte de dictionnaire pour faciliter son itération.

Exemple:

Dictionary<string, string> FD = new Dictionary<string,string>();
FD["name"] = data.name;
FD["age"] = data.age;
FD["occupation"] = data.occupation;
FD["email"] = data.email;
..........

Comment pourrais-je le faire facilement, sans saisir manuellement les 100 propriétés différentes?

Remarque: Les index de dictionnaire FD sont identiques aux noms de colonne de la base de données.

28
Dexter

En supposant que data est un objet et que vous souhaitez placer ses propriétés publiques dans un dictionnaire, vous pouvez essayer:

Original - ici pour des raisons historiques (2012) :

Dictionary<string, string> FD = (from x in data.GetType().GetProperties() select x)
    .ToDictionary (x => x.Name, x => (x.GetGetMethod().Invoke (data, null) == null ? "" : x.GetGetMethod().Invoke (data, null).ToString()));

Mise à jour (2017) :

Dictionary<string, string> dictionary = data.GetType().GetProperties()
    .ToDictionary(x => x.Name, x => x.GetValue(data)?.ToString() ?? "");
59
Yahia

La classe HtmlHelper permet une conversion de l'objet Anonymouns en RouteValueDictonary et je suppose que vous pouvez utiliser un .ToString () sur chaque valeur pour obtenir le repersentation de chaîne:

 var linkAttributes = System.Web.Mvc.HtmlHelper.AnonymousObjectToHtmlAttributes(linkHtmlAttributes);

L'inconvénient est que cela fait partie du framework ASP.NET MVC. À l'aide d'un réflecteur .NET, le code à l'intérieur de la méthode est le suivant:

public static RouteValueDictionary AnonymousObjectToHtmlAttributes(object htmlAttributes)
{
   RouteValueDictionary dictionary = new RouteValueDictionary();
  if (htmlAttributes != null)
  {
     foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(htmlAttributes))
     {
            dictionary.Add(descriptor.Name.Replace('_', '-'), descriptor.GetValue(htmlAttributes));
       }
 }
    return dictionary;
 }

Vous verrez que ce code est identique à la réponse que Yahia vous a donnée et que sa réponse fournit un Dictonary <string, string>. Avec le code reflété que je vous ai donné, vous pouvez facilement convertir un RouteValueDictionary en Dictonary <string, string>, mais la réponse de Yahia est un one-liner.

EDIT - J'ai ajouté le code de ce qui pourrait être une méthode pour effectuer votre conversion:

EDIT 2 - J'ai ajouté la vérification null au code et utilisé String.Format pour la valeur de chaîne

    public static Dictionary<string, string> ObjectToDictionary(object value)
    {
        Dictionary<string, string> dictionary = new Dictionary<string, string>();
        if (value != null)
        {
            foreach (System.ComponentModel.PropertyDescriptor descriptor in System.ComponentModel.TypeDescriptor.GetProperties(value))
            {
                if(descriptor != null && descriptor.Name != null)
                {
                     object propValue = descriptor.GetValue(value);
                     if(propValue != null)
                          dictionary.Add(descriptor.Name,String.Format("{0}",propValue));
            }
        }
        return dictionary;
    }

Et pour passer d'un dictionnaire à un objet, vérifiez http://automapper.org/ qui a été suggéré dans ce fil de discussion Convertissez le dictionnaire en objet anonyme

10
Nick Bork
var myDict = myObj.ToDictionary(); //returns all public fields & properties

.

public static class MyExtensions
{
    public static Dictionary<string, object> ToDictionary(this object myObj)
    {
        return myObj.GetType()
            .GetProperties()
            .Select(pi => new { Name = pi.Name, Value = pi.GetValue(myObj, null) })
            .Union( 
                myObj.GetType()
                .GetFields()
                .Select(fi => new { Name = fi.Name, Value = fi.GetValue(myObj) })
             )
            .ToDictionary(ks => ks.Name, vs => vs.Value);
    }
}
9
L.B

Jetez un coup d'œil à System.ComponentModel.TypeDescriptor.GetProperties( ... ). C’est ainsi que fonctionnent les bits de liaison de données normaux. Il utilisera la réflexion et vous retournera une collection de descripteurs de propriétés (que vous pourrez utiliser pour obtenir les valeurs). Vous pouvez personnaliser ces descripteurs pour performace en implémentant ICustomTypeDescriptor.

0
MaLio