F#中序列和列表之间的奇怪差异

时间:2010-12-15 15:53:26

标签: xaml f#

我遇到了F#中列表的奇怪问题。 我正在使用XamlXmlReader生成列表和序列,如:

let xaml_reader = XamlXmlReader(filename)
let nodes_seqs = seq { while xaml_reader.Read() do yield xaml_reader }

这段代码工作正常,但如果我对列表做同样的事情:

let xaml_reader2 = XamlXmlReader(filename)
let nodes_list = [ while xaml_reader2.Read() do yield xaml_reader2 ]

结果列表不正确,即序列的head元素包含正确的NodeType,LinePosition,LineNumber等,但列表的head元素是指向XAML中另一个地方的垃圾。例如:

let head_of_seq = Seq.head nodes_seq
let head_of_list = List.head nodes_list

我有:

  • head_of_seq.NodeType = NamespaceDeclaration
  • head_of_seq.LineNumber = 2
  • head_of_seq.LinePosition = 2

可是:

  • head_of_list.NodeType =无
  • head_of_list.LineNumber = 111
  • head_of_list.LinePosition = 30

XAML文件本身是正确的,由Microsoft Bend生成。有线索吗?我会感激任何帮助。

2 个答案:

答案 0 :(得分:4)

为什么要从序列或列表中产生XamlXmlReader本身?也就是说,你不应该使用yield xaml_reader.Value吗?

在任何一种情况下,您最终都会得到一个包含相同XamlXmlReader实例的序列(或列表)多次。当您迭代序列一次时,它看起来是正确的,因为读取器在读取每个元素时被提前一次。然而,即使你的序列几乎肯定没有按你的想法行事。例如,如果您尝试这样做会发生什么?

let first = Seq.head nodes_seqs
let first2 = Seq.head nodes_seqs

由于每次访问序列时都会提前XamlXmlReaderfirst2似乎指向第二个元素(并在first之后查看first2被评估将显示相同的事情。)

答案 1 :(得分:0)

从根本上说,List是固定的,而Sequence则是延迟评估的。确定序列的最佳方法是采用一些元素,并在其上调用toList()。

我建议尝试使用System.Linq.XML命名空间中的XElement和相关类,然后在舒适的时候转换到XAML阅读器。