Разве я не смогу потом перевести это обратно в XmlNodeList? Но если нет, то почему?
Нет, поскольку значение, возвращаемое из Skip
, не является XmlNodeList
. Он объявлен только как IEnumerable<XmlNode>
, и я ожидаю, что реализация Skip
, вероятно, будет использовать блок итератора ... конечно, я был бы удивлен, если бы Skip
имел какие-либо подробные знания о XmlNodeList
. Take
будет работать точно так же.
Лично я бы вообще не использовал старый API XML и просто использовал LINQ to XML. Это естественно работает с LINQ - и, как правило, лучше XML API, IMO.
У вас нет для этого, имейте в виду - вы могли бы просто изменить весь свой код, чтобы использовать IEnumerable<XmlNode>
вместо XmlNodeList
:
public static void eatSomeBananas(IEnumerable<XmlNode> subBananaNodeList, int numberOfBananas)
{
IEnumerable<XmlNode> bananasToEat = subBananaNodeList.Take(numberOfBananas);
IEnumerable<XmlNode> remainingBananas = subBananaNodeList.Skip(numberOfBananas);
// Added condition to avoid infinite recursion
if (remainingBananas.Any())
{
eatSomeBananas(remainingBananas, numberOfBananas);
}
}
Тогда вы можете просто вызвать Cast
один раз, когда вы вызываете метод:
eatSomeBananas(bananaNodeList.Cast<XmlNode>(), 2);
Вот версия LINQ to XML, которую я предпочитаю:
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
public class Test
{
public static void Main(string[] args)
{
XDocument someDoc = XDocument.Parse(
@"<bananas>
<banana tasty='yes'></banana>
<banana tasty='very'></banana>
<banana tasty='amazing'></banana>
<banana tasty='mind-blowing'></banana>
<banana tasty='disgusting'></banana>
</bananas>");
IEnumerable<XElement> bananas = someDoc.Descendants("banana");
EatSomeBananas(bananas, 2);
}
public static void EatSomeBananas(IEnumerable<XElement> bananas, int numberOfBananas)
{
var bananasToEat = bananas.Take(numberOfBananas);
Console.WriteLine("Eating some bananas");
foreach (var element in bananasToEat)
{
var tasty = element.Attribute("tasty").Value;
Console.WriteLine($"Tasty: {tasty}");
}
Console.WriteLine("Eaten the bananas");
var remainingBananas = bananas.Skip(numberOfBananas);
if (remainingBananas.Any())
{
EatSomeBananas(remainingBananas, numberOfBananas);
}
}
}
Обратите внимание, что для производственной реализации я бы избегал рекурсии и мог бы периодически материализовать результат - в противном случае он будет каждый раз повторяться с самого начала, пропуская загрузку, а затем принимая некоторые.