How can I convert a class into Dictionary<string,string>?

90,710

Solution 1

This is the recipe: 1 reflection, 1 LINQ-to-Objects!

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

Since I published this answer I've checked that many people found it useful. I invite everyone looking for this simple solution to check another Q&A where I generalized it into an extension method: Mapping object to dictionary and vice versa

Solution 2

Here a example with reflection without LINQ:

    Location local = new Location();
    local.city = "Lisbon";
    local.country = "Portugal";
    local.state = "None";

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

    Dictionary<string,string> dix = new Dictionary<string,string> ();

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

    foreach (string key in dix.Keys)
    {
        Console.WriteLine("nameProperty: {0}; value: {1}", key, dix[key]);
    }

    Console.Read();

Solution 3

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

I have used the above code. As simplified as possible and it works without reflection and the model could be nested and still work. (Change your code to not use Newtonsoft if you are using Json.net)

Solution 4

I would like to add an alternative to reflection, using JToken. You will need to check the benchmark difference between the two to see which has better performance.

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

Note this method is best for a flat class structure.

Solution 5

Give this a try.

This uses reflection to retrieve the object type, then all of the properties of the supplied object (PropertyInfo prop in obj.GetType().GetProperties(), see https://docs.microsoft.com/en-us/dotnet/api/system.type.getproperties?view=netcore-3.1). It then adds the property name as a key in the dictionary and, if a value exists, it adds the value, otherwise it adds null.

    public static Dictionary<string, object> ObjectToDictionary(object obj)
    {
        Dictionary<string, object> ret = new Dictionary<string, object>();

        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;
    }
Share:
90,710

Related videos on Youtube

Chintan
Author by

Chintan

Updated on July 08, 2022

Comments

  • Chintan
    Chintan almost 2 years

    Can I convert Class into Dictionary<string, string>?

    In Dictionary I want my class properties as keys and value of particular a property as the value.

    Suppose my class is

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

    Now suppose my data is

    city = Delhi
    state = Delhi
    country = India
    

    Now you can understand my point easily!

    I want to make a Dictionary! That dictionary should be like:

    Dictionary<string,string> dix = new Dictionary<string,string> ();
    dix.add("property_name", "property_value");
    

    I can get the value! But how can I get property names (not value)?

    What should I code to create it dynamic? That should work for every class which I want.

    You can understand this question as:

    How can I get a list of properties from particular class?

    Now again I am explaining one of my eagernesses about Dictionary! This question popuped in my mind from answer of my previous question!!

    • ilivewithian
      ilivewithian over 12 years
      Can you try to reword the question please? I have no real idea what you are trying to achieve.
    • Chintan
      Chintan over 12 years
      Insort ! I want all variables' name of particular class ! Is this possible ?
    • Matías Fidemraizer
      Matías Fidemraizer over 12 years
      @NoOne I've answered you, but you need to learn something more about OOP. You're talking about properties. And class-level "variables" are called fields. It's important to call everything by its name as understanding you'd easier than now! ;)
    • Chintan
      Chintan over 12 years
      @MatíasFidemraizer Sorry ! My mistake I should use "property" I have edited !
    • Tomer W
      Tomer W over 7 years
      @Chintan I dont know where you plan on using a dictionary of a class, note, that in contrary to your class where "Country" can be a property of type Country and city is of type string, in a dictionary you have to specify the most basic type you are going to store (most likely object) which will make your life harder further along the road.
    • Jim G.
      Jim G. about 2 years
  • drzaus
    drzaus almost 12 years
    what if I see "intrinsic" properties like "GenericEqualityComparer", rather than properties I explicitly declared? I've tried BindingFlags.DeclaredOnly.
  • drzaus
    drzaus almost 12 years
    UPDATE nevermind - I found that the method using this reflection (itself in an object extension) ended up calling itself with the converted result, so my extension was getting called on an object AND THEN on the resulting dictionary.
  • Kibitz503
    Kibitz503 over 11 years
    This saved me at least a days worth of work. Thanks so much I would vote you up twice if I could!
  • C0D3
    C0D3 over 10 years
    I can't compile this in Unity3D, am I missing an assembly reference?
  • Grant M
    Grant M almost 10 years
    For other Unity3D users - add usings to top and remember the code returns System.Oject not unity objects. using System.Collections.Generic; using System.Linq; using System.Reflection;
  • jon_darkstar
    jon_darkstar about 6 years
    var locationObject = locationObject.Value<JObject>();?
  • Makotosan
    Makotosan about 5 years
    Here's a more compact version: var props = JToken.FromObject(query) .Value<JObject>() .Properties() .ToDictionary(k => k.Name, v => $"{v.Value}");
  • Oliver
    Oliver almost 4 years
    It works but I'd argue if this is an extension method abstracting the logic the syntax of this is over compressed and obscured by the language "sugar". In a scenario like this I'd leave the logic in it's more verbose format as it makes it much easier to read.
  • Peter Mortensen
    Peter Mortensen over 3 years
    An explanation would be in order.
  • Peter Mortensen
    Peter Mortensen over 3 years
    An explanation would be in order.
  • Peter Mortensen
    Peter Mortensen over 3 years
    An explanation would be in order.
  • joelc
    joelc over 3 years
    Will amend the answer.
  • Tim Williams
    Tim Williams over 3 years
    When I try this it returns Dictionary<string, object> not Dictionary<string, string>, and thus does not satisfy the OP.
  • Matías Fidemraizer
    Matías Fidemraizer over 3 years
    @TimWilliams Thank you, I've fixed the issue ;-)
  • Hutch Moore
    Hutch Moore over 3 years
    @TimWilliams did you miss the cast to string?
  • R J
    R J about 3 years
    I'd imagine this method to be far less efficient (and I'm certain JsonModelSerializer is using reflection internally... So it doesn't really work without reflection.)
  • John M
    John M over 2 years
    Although not all properties will cast to string, so perhaps it's better to do this: prop => prop.GetValue(o, null)?.ToString() ?? ""
  • Matías Fidemraizer
    Matías Fidemraizer over 2 years
    @JohnM Right. BTW, check the OP's question. I just answered to fit OP's requirements.
  • Jay
    Jay about 2 years
    info.GetValue() may return null if the underlying property is null, so ToString() can throw an exception, might be worth to check the return value.