Miklós Tóth
Miklós Tóth

Reputation: 1511

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.

Upvotes: 0

Views: 240

Answers (2)

Mikl&#243;s T&#243;th
Mikl&#243;s T&#243;th

Reputation: 1511

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);

Upvotes: 0

Patrick Bell
Patrick Bell

Reputation: 769

You could store Type data alongside the JSON serialized data, but that seems like a rather inefficient method of accomplishing what you're trying to do. If your content isn't truely dynamic (e.g., the content changes, but the basic schema of the object is the same), you could just have precompiled classes for each JSON object type, and serialize the JSON into that class once you receive the data. This way, all of the type data would already be recognized by the compiler at runtime.

Upvotes: 1

Related Questions