将动态转换为对象

时间:2012-05-07 06:45:54

标签: c# dynamic-typing dynamictype

这是我的代码:

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

All()方法返回IEnumerable&lt; dynamic&gt;。我想将其转换为IEnumerable&lt; MyClass&gt;。上面的行没有工作,它说无法将'd__15'类型的对象强制转换为'System.Collections.Generic.IEnumerable`1 [MyClass]'。

我也尝试过:

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

但它返回null。

3 个答案:

答案 0 :(得分:6)

与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();

那是只是一个例子,我不希望它直接工作 - 我们不能做得更好,因为我们对你的结果实际返回的方式一无所知。

这听起来好像你在这里,我很害怕。

答案 1 :(得分:1)

您只需要投射每个单独的对象:

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

答案 2 :(得分:0)

在创建解决方案之前要解决的第一件事是对象在运行时将具有哪些类型。从您的评论中看到它们将是ExpandoObjects并假设MyClass不是从ExpandoObject派生的,您不能使用.Cast<T>方法,因为它只支持强制转换,而不支持自定义转换。

您可以使用JavaScriptSerializer

从ExpandoObjects转换

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

在你的情况下,你所要做的就是将转换中的转换答案改为转换。

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

这有点像hackish,因为JavaScriptSerializer并不打算这样做但它确实解决了这个问题。