2016-03-05 6 views
0

У меня есть динамический тип в C# (Content, тип, который наследует DynamicObject). Он обертывает внутренний объект JSON, содержащий данные. В TryGetMember Я возвращаю запрошенные свойства из этого внутреннего объекта JSON. Это работает просто отлично в случае простых типов (например, свойство int или string), потому что .Net правильно преобразует эти значения.Преобразование типа свойства DynamicObject на основе ReturnType

Но я хочу, чтобы использовать свойство с более сложными типами:

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

Проблема заключается в том, что в TryGetMember моего класса У меня нет никакого способа знать тип, который я должен преобразовать в (в данном случае IEnumerable Book), потому что binder.ReturnType всегда Объект. Согласно этой статье, это нормальное поведение: Determining the expected type of a DynamicObject member access

Но мне очень сложно поверить: как возможно, что API не дает мне знать тип цели? Таким образом, я должен заставить разработчиков использовать синтаксис метода для определения типа: явно

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

... что это некрасиво и странно.

ответ

0

Оказывается, это невозможно. Я закончил создание метода расширения (определяется в двух формах: для динамических коллекций и JArrays). Таким образом, я могу по крайней мере, получить коллекцию моего класса Content и все следующие решения работают:

Одна линия, но немного долго

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

Отдельные линии

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

Использование синтаксис вызова метода метода расширения (немного необычный).

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

Вы можете хранить данные Type вместе с сериализованными данными JSON, но это похоже на довольно неэффективный метод выполнения того, что вы пытаетесь сделать. Если ваш контент не truely динамический (например, содержимое изменяется, но основная схема объекта такая же), вы могли бы просто иметь предварительно скомпилированные классы для каждого типа объекта JSON и сериализовать JSON в этот класс, как только вы получить данные. Таким образом, все данные типа будут уже распознаны компилятором во время выполнения.

+0

К сожалению, данные поступают с сервера и являются действительно динамичными. Только вызывающий абонент знает, что определенное свойство является перечислимым для определенного типа. Спасибо за быстрый ответ! –