2012-05-07 2 views
6

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

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

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

Я также попытался:

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

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

+0

Как все() реализовано? – Tigran

+0

@ Тигран Вот он. Посмотрите на файл Massive.cs. https://github.com/robconery/massive –

+0

Любая причина, по которой вы не можете сохранить ее «динамической» в своем коде? –

ответ

6

Подобный ответ dbaseman (и комментарий AKX в) Я бы использовать Cast:

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

Вам потребуется using директиву LINQ:

using System.Linq; 

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

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

EDIT: Если вы хотите, чтобы иметь возможность доступа к значениям по индексу, я бы рекомендовал использовать ToList:

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

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

EDIT: Похоже, что ваши результаты на самом деле полны 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(); 

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

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

+0

И где искать мои ценности? [0], чаны [1]. К результату here.All() Я мог получить доступ к таким значениям, как –

+0

@srcee, если вы хотите иметь индексатор (вместо итерации всего списка), вам нужно будет добавить .ToArray() после вызова, чтобы выбрать –

+0

@ Srcee: вы можете * перебирать * по своим значениям только из последовательности, но если вам нужен индекс, вам понадобится список или массив. Но похоже, что вы новичок в C# и LINQ - в этом случае я бы посоветовал вам держаться подальше от динамического набора текста, если вы можете ... это затруднит понимание основ ... –

1

Вы просто должны бросить каждый отдельный объект:

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

'here.Cast ()' будет работать тоже, я думаю. – AKX

+0

@dbaseman Я получаю ошибку компилятора: нет метода выбора. –

+0

@Scree отредактировано. Извините, что неправильно изложил ваш вопрос. – McGarnagle

0

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

Там трюк вы можете использовать для преобразования из ExpandoObjects используя JavaScriptSerializer

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

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

в вашем случае, то все, что вам нужно сделать, это измените ответ Cast в skeets на Convert.

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

Это немного хака поскольку JavaScriptSerializer не должен был это сделать, но это не решает проблему.