7

这是我的代码:

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

All() 方法返回 IEnumerable<dynamic>。我想将其转换为 IEnumerable<MyClass>。上面的行不起作用,它说无法将类型“d__15”的对象转换为类型“System.Collections.Generic.IEnumerable`1[MyClass]”。

我也试过:

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

但它返回null。

4

3 回答 3

6

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

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

不过,您需要一个usingLINQ 指令:

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

只是一个示例,我不希望它立即起作用 - 我们不能做得比这更好,因为我们对您的结果实际上是如何返回的一无所知。

恐怕你在这里听上去有点不知所措。

于 2012-05-07T06:56:58.570 回答
1

您只需要转换每个单独的对象:

MyClass[] vats = here.All().Select(item => (MyClass)(dynamic)item).ToArray();
于 2012-05-07T06:50:01.417 回答
0

在创建解决方案之前首先要弄清楚对象在运行时将具有哪些类型。从您的评论中看到它们将成为 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);
    }
}

在您的情况下,您所要做的就是将 Cast in skeets 答案更改为 Convert。

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

这有点骇人听闻,因为 JavaScriptSerializer 并不是要这样做,但它确实解决了问题。

于 2012-05-07T07:18:40.213 回答