99 votes

Comment puis-je convertir une classe en Dictionary<string,string>?

Puis-je convertir une classe en Dictionary?

Dans le Dictionary, je veux que les propriétés de ma classe soient des clés et la valeur d'une propriété particulière soit la valeur.

Supposons que ma classe soit

public class Location
{
    public string city { get; set; }
    public string state { get; set; }
    public string country { get; set; }
}

Supposons maintenant que mes données soient

city = Delhi
state = Delhi
country = India

Vous pouvez maintenant comprendre mon point facilement!

Je veux créer un dictionnaire! Ce dictionnaire devrait ressembler à:

Dictionary dix = new Dictionary();
dix.add("nom_de_la_propriété", "valeur_de_la_propriété");

Je peux obtenir la valeur! Mais comment puis-je obtenir les noms des propriétés (pas des valeurs)?

Que devrais-je coder pour le rendre dynamique? Cela devrait fonctionner pour chaque classe que je veux.

Vous pouvez comprendre cette question comme:

Comment puis-je obtenir une liste de propriétés d'une classe particulière?

Je vais à nouveau expliquer l'une de mes envies concernant un Dictionary! Cette question a surgi dans mon esprit à partir de la réponse à ma <a href="https://stackoverflow.com/q/9209272/1162201">question précédente</a>!!

253voto

Matías Fidemraizer Points 16842

Ceci est la recette : 1 réflexion, 1 LINQ-to-Objects!

 someObject.GetType()
     .GetProperties(BindingFlags.Instance | BindingFlags.Public)
          .ToDictionary(prop => prop.Name, prop => (string)prop.GetValue(someObject, null))

Depuis que j'ai publié cette réponse, j'ai constaté que de nombreuses personnes l'ont trouvée utile. J'invite tout le monde à la recherche de cette solution simple à consulter une autre Q&R où je l'ai généralisée en une méthode d'extension : Mapping object to dictionary and vice versa

28voto

mark Dixon Points 9

Voici un exemple avec réflexion sans LINQ:

    Location local = new Location();
    local.city = "Lisbonne";
    local.country = "Portugal";
    local.state = "Aucun";

    PropertyInfo[] infos = local.GetType().GetProperties();

    Dictionary dix = new Dictionary ();

    foreach (PropertyInfo info in infos)
    {
        dix.Add(info.Name, info.GetValue(local, null).ToString());
    }

    foreach (string key in dix.Keys)
    {
        Console.WriteLine("nomPropriété: {0}; valeur: {1}", key, dix[key]);
    }

    Console.Read();

10voto

NetProvoke Points 140
public static Dictionary ToDictionary(object model)
    {
        var serializedModel = JsonModelSerializer.Serialize(model);
        return JsonModelSerializer.Deserialize<Dictionary<string, object>>(serializedModel);
    }

J'ai utilisé le code ci-dessus. Aussi simplifié que possible et ça fonctionne sans réflexion et le modèle peut être imbriqué et fonctionner toujours. (Modifiez votre code pour ne pas utiliser Newtonsoft si vous utilisez Json.net)

2voto

haxor Points 386

Essayez ceci.

Cela utilise la réflexion pour récupérer le type d'objet, puis toutes les propriétés de l'objet fourni (PropertyInfo prop in obj.GetType().GetProperties(), voir https://learn.microsoft.com/en-us/dotnet/api/system.type.getproperties?view=netcore-3.1). Ensuite, il ajoute le nom de la propriété comme clé dans le dictionnaire et, si une valeur existe, il ajoute la valeur, sinon il ajoute null.

    public static Dictionary ObjectToDictionary(object obj)
    {
        Dictionary ret = new Dictionary();

        foreach (PropertyInfo prop in obj.GetType().GetProperties())
        {
            string propName = prop.Name;
            var val = obj.GetType().GetProperty(propName).GetValue(obj, null);
            if (val != null)
            {
                ret.Add(propName, val);
            }
            else
            {
                ret.Add(propName, null);
            }
        }

        return ret;
    }

2voto

FishFingers Points 61

Je voudrais ajouter une alternative à la réflexion, en utilisant JToken. Vous devrez vérifier la différence de performance entre les deux pour voir lequel est le plus performant.

var location = new Location() { City = "Londres" };
var locationToken = JToken.FromObject(location);
var locationObject = locationObject.Value();
var locationPropertyList = locationObject.Properties()
    .Select(x => new KeyValuePair(x.Name, x.Value.ToString()));

Notez que cette méthode est la meilleure pour une structure de classe plate.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X