Convert Dynamic Objects

Here is my code:

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

The All () method returns an IEnumerable <dynamic>. I want to convert it to IEnumerable <MyClass>. The line above does not work, it says: "It is not possible to use an object like" d__15 "to enter" System.Collections.Generic.IEnumerable`1 [MyClass] ".

I also tried:

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

but it returns null.

+6
source share
3 answers

Like dbaseman's answer (and AKX's comment), I would use Cast :

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

You will need the using directive for LINQ:

 using System.Linq; 

at the top of the file. It looks like you don't have this if the Select method is not recognized.

Note that this assumes that each value is indeed a MyClass reference.

EDIT: if you want to have access to values ​​by index, I would recommend using ToList :

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

While ToArray will work too, I personally prefer lists over arrays in most cases, as they are more flexible.

EDIT: It looks like your results are actually full of ExpandoObject . You will need to create a new instance of MyClass from each element, for example.

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

or perhaps:

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

This is just an example that I would not expect to work right away - we cannot do anything better, because we do not know anything about how your results will return.

It sounds like you're on your head, I'm afraid.

+6
source

You just need to overlay each individual object:

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

The first thing you need to solve before you can create a solution is what the types of objects will have at runtime. Seeing from your comments that they will be ExpandoObjects and suggesting that MyClass is not the result of ExpandoObject, you cannot use the .Cast<T> method, since it only supports casts, not custom conversions.

Here is a trick you can use to convert from ExpandoObjects using JavaScriptSerializer

taking from this link here an extension method that you could use

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

in your case, then all you have to do is change Cast on skeets answer to Convert.

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

This is a bit hacky since the JavaScriptSerializer is not designed for this, but it solves the problem.

0
source

Source: https://habr.com/ru/post/915061/


All Articles