How can I convert a class into Dictionary<string,string>?
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;
}
Related videos on Youtube
Chintan
Updated on July 08, 2022Comments
-
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 over 12 yearsCan you try to reword the question please? I have no real idea what you are trying to achieve.
-
Chintan over 12 yearsInsort ! I want all variables' name of particular class ! Is this possible ?
-
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 over 12 years@MatíasFidemraizer Sorry ! My mistake I should use "property" I have edited !
-
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 typestring
, in a dictionary you have to specify the most basic type you are going to store (most likelyobject
) which will make your life harder further along the road. -
Jim G. about 2 yearsDoes this answer your question? How to convert object to Dictionary<TKey, TValue> in C#?
-
-
drzaus almost 12 yearswhat if I see "intrinsic" properties like "GenericEqualityComparer", rather than properties I explicitly declared? I've tried
BindingFlags.DeclaredOnly
. -
drzaus almost 12 yearsUPDATE 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 over 11 yearsThis saved me at least a days worth of work. Thanks so much I would vote you up twice if I could!
-
C0D3 over 10 yearsI can't compile this in Unity3D, am I missing an assembly reference?
-
Grant M almost 10 yearsFor 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 about 6 years
var locationObject = locationObject.Value<JObject>();
? -
Makotosan about 5 yearsHere's a more compact version:
var props = JToken.FromObject(query) .Value<JObject>() .Properties() .ToDictionary(k => k.Name, v => $"{v.Value}");
-
Oliver almost 4 yearsIt 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 over 3 yearsAn explanation would be in order.
-
Peter Mortensen over 3 yearsAn explanation would be in order.
-
Peter Mortensen over 3 yearsAn explanation would be in order.
-
joelc over 3 yearsWill amend the answer.
-
Tim Williams over 3 yearsWhen I try this it returns Dictionary<string, object> not Dictionary<string, string>, and thus does not satisfy the OP.
-
Matías Fidemraizer over 3 years@TimWilliams Thank you, I've fixed the issue ;-)
-
Hutch Moore over 3 years@TimWilliams did you miss the cast to string?
-
R J about 3 yearsI'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 over 2 yearsAlthough not all properties will cast to string, so perhaps it's better to do this:
prop => prop.GetValue(o, null)?.ToString() ?? ""
-
Matías Fidemraizer over 2 years@JohnM Right. BTW, check the OP's question. I just answered to fit OP's requirements.
-
Jay about 2 yearsinfo.GetValue() may return null if the underlying property is null, so ToString() can throw an exception, might be worth to check the return value.