2012-05-07 10 views
6

Ecco il mio codice:Conversione dinamica di opporsi

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

Il metodo Tutti() restituisce IEnumerable < dinamica>. Voglio convertirlo in IEnumerable < MyClass>. La riga sopra non funziona, dice Non è possibile eseguire il cast dell'oggetto di tipo 'd__15' per digitare 'System.Collections.Generic.IEnumerable`1 [MyClass]'.

Ho anche provato:

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

ma restituisce null.

+0

Come viene implementato All()? – Tigran

+0

@Tigran Eccolo. Guarda il file Massive.cs. https://github.com/robconery/massive –

+0

Qualsiasi motivo non è possibile mantenerlo "dinamico" nel codice? –

risposta

6

Simile alla risposta di dbaseman (e commento di AKX) userei Cast:

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

avrete bisogno di una direttiva using per LINQ però:

using System.Linq; 

nella parte superiore del file. Sembra che tu non l'abbia ottenuto se il metodo Select non viene riconosciuto.

Si noti che questo presuppone che ciascun valore in realtà è un riferimento MyClass.

EDIT: Se si vuole essere in grado di accedere ai valori dell'indice, mi consiglia di utilizzare ToList:

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

Mentre ToArray avrebbe funzionato troppo, io personalmente preferisco elenca oltre array nella maggior parte dei casi, come sono piuttosto più flessibili.

MODIFICA: Sembra che i risultati siano effettivamente pieni di ExpandoObject. Dovrai creare una nuova istanza di MyClass da ciascun elemento, ad es.

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

o, eventualmente:

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

Questo è solo un esempio, che non mi aspetto di lavorare subito - non possiamo fare meglio di così come sappiamo nulla di come i tuoi risultati vengono effettivamente restituiti.

Sembra proprio che tu sia fuori di testa qui, temo.

+0

E dove cercare i miei valori? [0], vats [1]. Per il risultato here.All() potrei accedere a quei valori come quello –

+0

@srcee se desideri avere un indicizzatore (anziché iterare l'intero elenco) avresti bisogno di appenare .ToArray() dopo la chiamata per selezionare –

+0

@ Srcee: puoi * iterare * sui tuoi valori solo da una sequenza, ma se vuoi un indicizzatore avrai bisogno di un elenco o di un array. Ma sembra che tu sia abbastanza nuovo per C# e LINQ - nel qual caso ti suggerirei di stare alla larga da una digitazione dinamica per un po 'se puoi ... renderà più difficile capire le basi ... –

1

Non vi resta che lanciare ogni singolo oggetto:

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

'here.Cast ()' potrebbe funzionare anche, suppongo. – AKX

+0

@dbaseman Ricevo l'errore del compilatore: non esiste un metodo Select. –

+0

@Scree modificato. Mi dispiace, ho letto male la tua domanda. – McGarnagle

0

La prima cosa da capire prima di poter creare una soluzione è quale tipo gli oggetti avranno in fase di esecuzione. Vedendo dai tuoi commenti che stanno per essere ExpandoObjects e supponendo che MyClass non derivi da ExpandoObject non puoi usare il metodo .Cast<T> poiché supporta solo i cast e non le conversioni personalizzate.

C'è un trucco è possibile utilizzare per convertire da ExpandoObjects utilizzando il JavaScriptSerializer

prendere da questo link qui un metodo di estensione che si potrebbe usare

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

nel tuo caso, allora tutto ciò che dovete fare è cambia la risposta Cast in skeets a Converti.

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

Questo è un po 'hackerato dal momento che JavaScriptSerializer non è stato progettato per farlo ma risolve il problema.