Search code examples
c#dynamictypespropertiesdynamicobject

Converting type of a property of a DynamicObject based on ReturnType


I have a dynamic type in C# (Content, a type that inherits DynamicObject). It wraps an inner JSON object containing the data. In TryGetMember I return the requested properties from this inner JSON object. This works just fine in case of simple types (e.g. an int or string property), because .Net converts those values correctly.

But I want to use properties with more complex types:

dynamic content = Content.Load(id); 
IEnumerable<Book> bookList = content.Books;

The problem is that in TryGetMember of my class I have no way to know the type that I should convert to (in this case the IEnumerable Book), because binder.ReturnType is always Object. According to this article, this is the normal behavior: Determining the expected type of a DynamicObject member access

But I find this very hard to believe: how is it possible that the API does not let me know the target type? This way I will have to force developers to use the method syntax to specify the type explicitely:

IEnumerable<Books> bookList = content.Books<IEnumerable<Book>>();

...which is ugly and weird.


Solution

  • It turns out that this is not possible indeed. I ended up creating an extension method (defined in two forms: for dynamic collections and JArrays). That way I can at least get a collection of my Content class and all of the following solutions work:

    One line, but a bit long

    var members = ((IEnumerable<dynamic>)group.Members).ToContentEnumerable();    
    

    Separate lines

    IEnumerable<dynamic> members = adminGroup.Members;
    foreach (dynamic member in members.ToContentEnumerable())
    {
        //...
    }
    

    Using the method call syntax of the extension method (a bit unusual).

    var members = ContentExtensions.ToContentEnumerable(group.Members);