Look at the following example:
void Main()
{
    // APPROACH 1: With an anonymous type
    var myObject = new {
        Property1 = "PropertyValue1"
    };
    // WORKS: Properties contains "Property1"
    var properties = myObject.GetType().GetProperties();
    // APPROACH 2: With an expando object
    dynamic myObject2 = new ExpandoObject();
    myObject2.Property1 = "PropertyValue1";
    // DOES NOT WORK: Properties2 is null or empty
    var properties2 = myObject2.GetType().GetProperties();
}
What I want is to make Type.GetProperties() to work on a dynamically generated type. I really understand why it works in the approach 1 and not 2. Actually, in the approach 1, the compiler has the oportunity to generate an anonymous type that looks exactly like a named type. In the approach 2, however, the compile time type is actually an ExpandoObject, so reflection doesn't work properly.
How do I create a runtime object, that is dynamic and will also work normally with reflection, like the GetProperties method?
EDIT
Thanks for all answers, but I really understand and I know how to get the keys and values from the ExpandoObject.. The problem is that I need to pass a dynamically created instance to a method, outside my control that will, in turn, call GetProperties() on the instance.
You don't need reflection with ExpandoObject. It's really just a fancy implementation of IDictionary<string, object>. You can cast it as such, and then you will have a dictionary where the keys are the property names and the values are the property values:
// Create your object
dynamic myObject2 = new ExpandoObject();
// Cast to IDictionary<string, object>
var myObjectDictionary = (IDictionary<string, object>)myObject2;
// Get List<string> of properties
var propertyNames = myObjectDictionary.Keys.ToList();
Another option would be to use the features of an IDynamicMetaObjectProvider, which ExpandoObject also implements. Usage would look like:
var metaObjectProvider = (IDynamicMetaObjectProvider)myObject2;
var propertyNames = metaObjectProvider
    .GetMetaObject(Expression.Constant(metaObjectProvider))
    .GetDynamicMemberNames();
In this case propertyNames would be an IEnumerable<string> with the dynamic member names.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With