我遇到了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
我有:
可是:
XAML文件本身是正确的,由Microsoft Bend生成。有线索吗?我会感激任何帮助。
答案 0 :(得分:4)
为什么要从序列或列表中产生XamlXmlReader
本身?也就是说,你不应该使用yield xaml_reader.Value
吗?
在任何一种情况下,您最终都会得到一个包含相同XamlXmlReader
实例的序列(或列表)多次。当您迭代序列一次时,它看起来是正确的,因为读取器在读取每个元素时被提前一次。然而,即使你的序列几乎肯定没有按你的想法行事。例如,如果您尝试这样做会发生什么?
let first = Seq.head nodes_seqs
let first2 = Seq.head nodes_seqs
由于每次访问序列时都会提前XamlXmlReader
,first2
似乎指向第二个元素(并在first
之后查看first2
被评估将显示相同的事情。)
答案 1 :(得分:0)
从根本上说,List是固定的,而Sequence则是延迟评估的。确定序列的最佳方法是采用一些元素,并在其上调用toList()。
我建议尝试使用System.Linq.XML命名空间中的XElement和相关类,然后在舒适的时候转换到XAML阅读器。