2012-05-07 1 views
6

Voici mon code:Conversion dynamique pour objet

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

La méthode Tous() retourne IEnumerable < dynamique>. Je veux le convertir en IEnumerable < MyClass>. La ligne ci-dessus ne fonctionne pas, elle indique Impossible de lancer l'objet de type 'd__15' pour taper 'System.Collections.Generic.IEnumerable`1 [MyClass]'.

J'ai aussi essayé:

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

mais il renvoie NULL.

+0

Comment tout() est implémenté? – Tigran

+0

@Tigran La voici. Regardez le fichier Massive.cs. https://github.com/robconery/massive –

+0

Une raison pour laquelle vous ne pouvez pas le garder "dynamique" dans votre code? –

Répondre

6

similaires à la réponse de dbaseman (et commentaire de AKX) J'utilise Cast:

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

Vous aurez besoin d'une directive using pour LINQ si:

using System.Linq; 

en haut de votre fichier. Il semble que vous ne l'ayez pas obtenu si la méthode Select n'est pas reconnue. Notez que cela suppose que chaque valeur vraiment est une référence MyClass.

EDIT: Si vous voulez être en mesure d'accéder aux valeurs par index, je vous recommande d'utiliser ToList:

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

Alors que ToArray fonctionnerait aussi, je suis personnellement en faveur des listes sur les tableaux dans la plupart des cas, comme ils sont plutôt plus flexibles.

EDIT: Il semble que vos résultats soient réellement remplis de ExpandoObject. Vous devrez créer une nouvelle instance de MyClass à partir de chaque élément, par ex.

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

ou peut-être:

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

C'est juste un exemple, que je ne serais pas attendre à travailler tout de suite - nous ne pouvons pas faire mieux que nous ne savons rien sur la façon dont Vos résultats sont en train d'être retournés.

On dirait que vous êtes dans la tête ici, j'ai peur.

+0

Et où chercher mes valeurs? [0], cuves [1]. Au résultat ici.Tout() je pourrais accéder à ces valeurs comme cela –

+0

@srcee si vous souhaitez avoir un indexeur (au lieu d'itérer toute la liste), vous devez appenez .ToArray() après l'appel pour sélectionner –

+0

@ Srcee: Vous pouvez * itérer * sur vos valeurs à partir d'une séquence, mais si vous voulez un indexeur, vous aurez besoin d'une liste ou d'un tableau. Mais on dirait que vous êtes assez nouveau pour C# et LINQ - dans ce cas, je vous suggère de rester loin de la dactylographie dynamique pendant un certain temps si vous le pouvez ... ça va rendre plus difficile à comprendre les bases ... –

1

Il vous suffit de jeter chaque objet:

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

'here.Cast ()' fonctionnerait aussi, je suppose. – AKX

+0

@dbaseman J'obtiens une erreur de compilation: il n'y a pas de méthode Select. –

+0

@Scree édité. Désolé à ce sujet, mal interprété votre question. – McGarnagle

0

La première chose à faire avant de pouvoir créer une solution est de savoir quels types les objets auront à l'exécution. Voyant à partir de vos commentaires qu'ils vont être ExpandoObjects et en supposant que MyClass ne dérive pas d'ExpandoObject, vous ne pouvez pas utiliser la méthode .Cast<T> car elle ne prend en charge que les conversions et non les conversions personnalisées.

Il y a un truc que vous pouvez utiliser pour convertir ExpandoObjects en utilisant la JavaScriptSerializer

prendre de ce link ici une méthode d'extension que vous pouvez utiliser

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

dans votre cas, alors tout ce que vous avez à faire est changez la réponse Cast to skeets en Convert.

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

Ceci est un peu hackish puisque le JavaScriptSerializer n'était pas destiné à le faire mais il résout le problème.