Я читал кусок кода из библиотеки «XStreamingReader» (который кажется действительно классным решением для возможности выполнения запросов LINQ над документами XML, но без загрузки фактического документа в память (как в объекте XDocument)и задавался вопросом о следующем:
public IEnumerable<XElement> Elements()
{
using (var reader = readerFactory())
{
reader.MoveToContent();
MoveToNextElement(reader);
while (!reader.EOF)
{
yield return XElement.Load(reader.ReadSubtree());
MoveToNextFollowing(reader);
}
}
}
public IEnumerable<XElement> Elements(XName name)
{
return Elements().Where(x => x.Name == name);
}
Относительно второго метода Elements(XName)
- Метод сначала вызывает Elements (), а затем использует Where()
для фильтрации результатов, но я заинтриговано порядке выполнения здесь, так как Elements () содержит оператор yield. Из того, что я понимаю: - Выполнение Elements () возвращает коллекцию IEnumerable, эта коллекция физически не содержит никаких элементов YET. - Где () выполняется в этой коллекциипозади сцены есть цикл, который перебирает каждый элемент, новые элементы «загружаются» на лету, так как используется yield. - Все элементы, которые соответствуют выражению Where, возвращаются как коллекция IEnumerable и физически находятся в этой коллекции..
Во-первых, яправильно с приведенным выше предположением?Во-вторых, в случае, если я прав - что, если я хотел бы вернуть «подданную» коллекцию, а не возвращать коллекцию, которая физически заполнена всеми отфильтрованными данными?Я спрашиваю об этом, потому что он теряет всю цель НЕ читать весь «соответствующий» блок в память, а выполнять итерацию одного соответствующего элемента за раз ...