0

I need a way to convert a Dictionary to a strongly typed object. Im aware that I could use reflection and simply create a new object of the type I want and then just iterate through the properties and assign them.. basically.. https://dotnetfiddle.net/yz9GPd

However.. this seems to me to be super inefficient.. so is there any good way to improve this?.. and also a way to use less reflection (since thats usually quite costly). Maybe some way to do this using Compiled Expressions/Functions?

Inx51
  • 1,911
  • 3
  • 24
  • 44
  • Why do you say you need to convert a dictionary to a "strongly typed object"? Can I assume a "strongly typed object" is an instance of a class? (Edit: I liked the JSON idea; it fit the Stack Overflow definition of "efficiency"). – 15ee8f99-57ff-4f92-890c-b56153 May 21 '19 at 20:21
  • Using `JSON` to concrete object may be faster if you implement a custom `JsonReader` it may be better, not for sure without testing, as JSON deserialization uses `Reflection` as well, you can check out this post and see if it sounds like a viable option (https://stackoverflow.com/questions/26380184/how-to-improve-json-deserialization-speed-in-net-json-net-or-other) – Ryan Wilson May 21 '19 at 20:28
  • @EdPlunkett, guess you could call it an instance of a class as well.. the important point is that its strongly typed.. for instance not an ExpandoObject.. – Inx51 May 21 '19 at 20:33
  • @RyanWilson, have considered that.. but as you mention, it also uses reflection which is fairly slow.. – Inx51 May 21 '19 at 20:33
  • @Inx51 Why do you say you need to convert a dictionary to whatever it is? Anyway, just write a method with a bunch of `this.Blah = d["Blah"];` if regular serialization is too slow. If you don't like all the typing, consider some kind of property mapping via attributes (also lots of typing), or code generation. – 15ee8f99-57ff-4f92-890c-b56153 May 21 '19 at 20:33
  • I would solve the cause of this first, it seems unusual that you are in this situation – TheGeneral May 21 '19 at 20:34
  • 1
    Have you measured the performance to determine it's actually too slow? – 15ee8f99-57ff-4f92-890c-b56153 May 21 '19 at 20:40
  • Using a simple Stopwatch, the method I provided took 200ms for 100000 items.. so that might be fairly ok anyways actually.. since most of the time it wont be 100000 items.. another approach that struck me would be to create a some proxy-solution.. – Inx51 May 21 '19 at 20:47
  • 1
    You could use AutoMapper - it supports mapping `IDictionary` to a strong type - http://docs.automapper.org/en/stable/Dynamic-and-ExpandoObject-Mapping.html – shf301 May 21 '19 at 21:44

1 Answers1

1

You could use something like FastMember which is using Reflection.Emit to map to the members of your class with their names as strings. It's fast compared to standard reflection, but difficult to write if you're doing it yourself.

Using that library, your example would look like this:

Dictionary<string, object> values = new Dictionary<string, object>()
{
    { "Property1", "MyValue" },
    { "Property2", 1234 },
    { "Property3", true },
};

MyType myType = new MyType();
var accessor = TypeAccessor.Create(typeof(MyType));
foreach (var entry in values)
    accessor[myType, entry.Key] = entry.Value;
steve16351
  • 5,372
  • 2
  • 16
  • 29