I want to take an anonymous object as argument to a method, and then iterate over its properties to add each property/value to a a dynamic ExpandoObject
.
So what I need is to go from
new { Prop1 = "first value", Prop2 = SomeObjectInstance, Prop3 = 1234 }
to knowing names and values of each property, and being able to add them to the ExpandoObject
.
How do I accomplish this?
Side note: This will be done in many of my unit tests (I'm using it to refactor away a lot of junk in the setup), so performance is to some extent relevant. I don't know enough about reflection to say for sure, but from what I've understood it's pretty performance heavy, so if it's possible I'd rather avoid it...
Follow-up question:
As I said, I'm taking this anonymous object as an argument to a method. What datatype should I use in the method's signature? Will all properties be available if I use object
?
Reflect on the anonymous object to get its property names and values, then take advantage of an ExpandoObject actually being a dictionary to populate it. Here's an example, expressed as a unit test:
This is an old question, but now you should be able to do this with the following code:
The output would look like the following:
Use Reflection.Emit to create a generic method to fill an ExpandoObject.
OR use Expressions perhaps (I think this would only be possible in .NET 4 though).
Neither of these approaches uses reflection when invoking, only during setup of a delegate (which obviously needs to be cached).
Here is some Reflection.Emit code to fill a dictionary (I guess ExpandoObject is not far off);
An alternative approach is to use
DynamicObject
instead ofExpandoObject
, and that way you only have the overhead of doing the reflection if you actually try to access a property from the other object.Now it only does the reflection when you actually try to access the property via a dynamic get. On the downside, if you repeatedly access the same property, it has to do the reflection each time. So you could cache the result:
You could support storing a list of target objects to coalesce their properties, and support setting properties (with a similar override called TrySetMember) to allow you to dynamically set values in the cache dictionary.
Of course, the overhead of reflection is probably not going to be worth worrying about, but for large objects this could limit the impact of it. What is maybe more interesting is the extra flexibility it gives you.
you have to use reflection.... (code "borrowed" from this url)