将动态转换为对象

本文关键字:对象 转换 动态 | 更新日期: 2023-09-27 18:33:26

这是我的代码:

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

但它返回空值。

将动态转换为对象

类似于 dbaseman 的答案(和 AKX 的评论(,我会使用 Cast

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

不过,您需要一个 LINQ 的using指令:

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> 方法,因为它只支持强制转换而不是自定义转换。

有一个技巧可以用来使用 JavaScriptSerializer 从 ExpandoObjects 转换

从此链接中获取您可以使用的扩展方法

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并不是为了这样做,但它确实解决了这个问题。