【问题标题】:LINQ-to-List and IEnumerable issuesLINQ-to-List 和 IEnumerable 问题
【发布时间】:2009-09-19 19:23:34
【问题描述】:

我正在使用 LINQ-to-XML 查询 HTML 文件。它看起来像这样:

<html>
    <body>
        <div class="Players">
        <div class="role">Goalies</div>
        <div class="name">John Smith</div>
        <div class="name">Shawn Xie</div>
        <div class="role">Right Wings</div>
        <div class="name">Jack Davis</div>
        <div class="name">Carl Yuns</div>
        <div class="name">Wayne Gortonia</div>
        <div class="role">Centers</div>
        <div class="name">Lutz Gaspy</div>
        <div class="name">John Jacobs</div>
        </div>
    </body>
</html>

我要做的是创建一个这些人的列表,就像在一个名为 Players 的结构列表中:

Structure Players
    Public Name As String
    Public Position As String
End Structure

但我很快发现我真的不知道我在做 LINQ 时在做什么。

我的查询已经到此为止了:

Dim goalieList = From d In player.Elements _
                 Where d.Value = "Goalies" _
                 Select From g In d.ElementsAfterSelf _
                 Take While (g.@class <> "role") _
                 Select New Players With {.Position = "Goalie", _
                         .Name = g.Value}

Dim centersList = From d In player.Elements _
                  Where d.Value = "Centers" _
                  Select From g In d.ElementsAfterSelf _
                  Take While (g.@class <> "role") _
                  Select New Players With {.Position = "Centers", _
                         .Name = g.Value}

这让我按位置了解球员,但后来我对此无能为力,结果类型为System.Collections.Generic.IEnumerable(Of System.Collections.Generic.IEnumerable(Of Player))

我想要做的是将这两个结果添加到一个新列表中,例如:

Dim playersList As List(Of Players) = Nothing
playersList.AddRange(centersList)
playersList.AddRange(goalieList)

这样我就可以查询列表并使用它。但它会引发错误:

无法转换类型的对象 'WhereSelectEnumerableIterator2[System.Xml.Linq.XElement,System.Collections.Generic.IEnumerable1[Players]]' 输入 'System.Collections.Generic.IEnumerable`1[Players]'

如您所见,我可能真的不知道如何处理所有这些对象/类。有没有人知道我可能做错了什么以及如何解决它?

已解决:LINQ 查询需要返回单个 IEnumerable,如下所示:

Dim goalieList = From l In _
                    (From d In players.Elements _
                     Where d.Value = "Goalies" _
                     Select d.ElementsAfterSelf.TakeWhile(Function(f) f.@class <> "role")) _
                  Select New Players With {.Position = "Goalie", .Name = l.Value}

然后使用goalieList.ToList

【问题讨论】:

  • 有几种方法可以做到这一点。我在下面的回答是完全按照您的意愿行事的一种方法。您还可以使用 Linq 的 Set 操作来创建结果的联合。您还可以构造一个查询,以一组形式返回结果,
  • @Peter Mortensen:好眼力!我已经解决了,谢谢指出。
  • 啊,你是对的。现在修好了。再次感谢

标签: vb.net linq linq-to-xml ienumerable


【解决方案1】:

我在 VB 中失败了,但在 C# 中,您会在 centerList 和goalieList 上调用 ToList()。

比如:

playersList.AddRange(centersList.ToList())
playersList.AddRange(goalieList.ToList())

【讨论】:

  • 你在这里给了我一个很好的提示。我想通了,我相信。问题是我有两个选择语句,它们在 iEnumerable 中创建了一个 iEnumerable。我将代码更改为: Dim goalieList = From l In (From d In player.Elements Where d.Value = "Goalies" Select d.ElementsAfterSelf.TakeWhile(Function(f) f.@class "role")) 选择具有 {.Position = "Goalie", .Name = l.Value} 的新玩家,然后返回单个 iEnumerable。有了这个,我按照你的建议做 - playerList.AddRange(goalieList.ToList()) - 它有效!
【解决方案2】:

你有两个玩家职业的机会吗?否则,我看不出你怎么可能得到那个错误信息。

查看反射器,WhereSelectEnumerableIterator 实现了 IEnumerable,所以转换应该成功。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-12-18
    • 2010-09-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多