为什么 XmlReader 在返回 IEnumerable<T> 时关闭?
Why is the XmlReader getting closed when returning an IEnumerable<T>?
我有以下扩展方法:
public static IEnumerable<XElement> GetElement(this XmlReader reader, string elementName)
{
reader.MoveToElement();
while (!reader.EOF)
{
if (reader.NodeType == XmlNodeType.Element
&& reader.Name.Equals(elementName))
{
yield return XNode.ReadFrom(reader) as XElement;
}
reader.Read();
}
}
public static IEnumerable<XElement> ExtractElement(this Stream stream, string elementName)
{
using (var reader = XmlReader.Create(stream))
{
return reader.GetElement(elementName));
}
}
然后我尝试打开 FileStream
并使用以下方法获取 XML
文件中的特定元素:
using (var stream = File.Open("My.xml", FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
var element = stream.ExtractElement("subscriptionForms").First();
element.Elements("subscriptionForm").Count().ShouldBe(11);
}
但是 运行 由于 xml reader 关闭(reader.EOF
为 false
和 reader.Read()
什么也没做)但是当我更改以下行时:
return reader.GetElement(elementName));
至:
foreach (var xElement in reader.GetElement(elementName, ignoreCase))
{
yield return xElement;
}
似乎一切正常。为什么前一个实现导致 reader 关闭?
reader.GetElement(elementName)
尚未开始枚举。它 return 是一个对象,一旦您查看它包含的内容,就会从 reader
开始读取。由于您直接 return 该对象,并且 return
语句包含在 using
中,因此 using
语句导致 reader 在枚举开始之前关闭.
当你将它包裹在 foreach
循环中时,using
语句关闭 reader 的效果会延迟到 foreach
终止,到那时它会好的,到时候你就不再需要 reader.
我有以下扩展方法:
public static IEnumerable<XElement> GetElement(this XmlReader reader, string elementName)
{
reader.MoveToElement();
while (!reader.EOF)
{
if (reader.NodeType == XmlNodeType.Element
&& reader.Name.Equals(elementName))
{
yield return XNode.ReadFrom(reader) as XElement;
}
reader.Read();
}
}
public static IEnumerable<XElement> ExtractElement(this Stream stream, string elementName)
{
using (var reader = XmlReader.Create(stream))
{
return reader.GetElement(elementName));
}
}
然后我尝试打开 FileStream
并使用以下方法获取 XML
文件中的特定元素:
using (var stream = File.Open("My.xml", FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
var element = stream.ExtractElement("subscriptionForms").First();
element.Elements("subscriptionForm").Count().ShouldBe(11);
}
但是 运行 由于 xml reader 关闭(reader.EOF
为 false
和 reader.Read()
什么也没做)但是当我更改以下行时:
return reader.GetElement(elementName));
至:
foreach (var xElement in reader.GetElement(elementName, ignoreCase))
{
yield return xElement;
}
似乎一切正常。为什么前一个实现导致 reader 关闭?
reader.GetElement(elementName)
尚未开始枚举。它 return 是一个对象,一旦您查看它包含的内容,就会从 reader
开始读取。由于您直接 return 该对象,并且 return
语句包含在 using
中,因此 using
语句导致 reader 在枚举开始之前关闭.
当你将它包裹在 foreach
循环中时,using
语句关闭 reader 的效果会延迟到 foreach
终止,到那时它会好的,到时候你就不再需要 reader.