Преобразование динамического объекта

Вот мой код:

MyClass here = new MyClass();
IEnumerable<MyClass> vats = (IEnumerable<MyClass>)here.All();

Метод All() возвращает IEnumerable. Я хочу преобразовать его в IEnumerable. Строка выше не работает, она говорит, что Невозможно привести объект типа 'd__15' к типу 'System.Collections.Generic.IEnumerable`1[MyClass]'.

Я также попробовал:

 IEnumerable<MyClass> vats = here.All() as IEnumerable<MyClass>;

но он возвращает ноль.

3 ответа

Решение

Аналогично ответу dbaseman (и комментарию AKX) я бы использовал Cast:

IEnumerable<MyClass> vats = here.All().Cast<MyClass>();

Вам понадобится using Директива для LINQ, хотя:

using System.Linq;

в верхней части вашего файла. Похоже, у вас этого нет, если Select метод не распознан.

Обратите внимание, что это предполагает, что каждое значение действительно MyClass ссылка.

РЕДАКТИРОВАТЬ: Если вы хотите иметь доступ к значениям по индексу, я бы рекомендовал использовать ToList:

List<MyClass> vats = here.All().Cast<MyClass>().ToList();

В то время как ToArray будет работать, я лично предпочитаю списки над массивами в большинстве случаев, так как они более гибкие.

РЕДАКТИРОВАТЬ: кажется, что ваши результаты на самом деле полны ExpandoObject, Вам нужно будет создать новый экземпляр MyClass от каждого предмета, например

List<MyClass> vats = here.All()
                         .Select(item => new MyClass(item.Name, item.Value))
                         .ToList();

или возможно:

List<MyClass> vats = here.All()
                         .Select(item => new MyClass {
                                     Name = item.Name,
                                     Value = item.Value,
                                 })
                         .ToList();

Это всего лишь пример, который я не ожидал бы, что он сработает сразу - мы не можем добиться большего успеха, поскольку ничего не знаем о том, как на самом деле возвращаются ваши результаты.

Боюсь, это звучит так, будто ты здесь над головой.

Вам просто нужно разыграть каждый отдельный объект:

MyClass[] vats = here.All().Select(item => (MyClass)(dynamic)item).ToArray();

Прежде чем вы сможете создать решение, прежде всего необходимо определить, какие типы будут иметь объекты во время выполнения. Видя из ваших комментариев, что они будут ExpandoObjects и предполагая, что MyClass не является производным от ExpandoObject, вы не можете использовать .Cast<T> метод, поскольку он поддерживает только приведения, а не пользовательские преобразования.

Есть трюк, который вы можете использовать для преобразования из ExpandoObjects с помощью JavaScriptSerializer

взяв по этой ссылке здесь метод расширения, который вы могли бы использовать

public static IEnumerable<T> Convert<T>(this IEnumerable<dynamic> self){
    var jsSerializer = new JavaScriptSerializer();
    foreach(var obj in self){
        yield return jsSerializer.ConvertToType<T>(obj);
    }
}

тогда в вашем случае все, что вам нужно сделать, это изменить ответ "В ролях скит" на "Преобразовать".

List<MyClass> vats = here.All().Convert<MyClass>().ToList();

Это немного нелепо, поскольку JavaScriptSerializer не предназначен для этого, но он решает проблему.

Другие вопросы по тегам