递归和收益 return
Recursion and Yield return
我有一个方法 HandleChildItems
,它 return 是一个 IEnumerable<object>
。这个方法又调用了一个方法GetChildItems
。在 GetChildItems
方法中,我进行递归调用以将项目添加到列表中,然后 GetChildItems
方法 return 将列表返回到 HandleChildItems
方法。
return 它作为 IEnumerable
我是 运行 foreach
在 HandleChildItems
方法的项目列表上循环 yield return
.
但这似乎需要更多时间,因为我的 xml 文件有超过 10 万个条目。
有没有办法在调用递归方法本身的同时处理这个问题?
private IEnumerable<object> HandleChildItems()
{
var childItemslst = new List<Item>();
childItemslst = GetChildItems(xmlnode);
foreach (var item in childItemslst)
{
yield return item ;
}
}
private List<Item> GetchildItems(XMLnodeList nodeList)
{
List<Item> lstItem = new List<Item>();
// Here I recursively call the method to add the items to list
foreach (xmlnode xn in nodeList)
{
if (xn.childnodes.count > 0)
{
GetChildItems(xn.childnodes);
}
else
{
item = new Item
{
Code = "123",
Itemtext = "xyz"
};
}
lstItem.add(item);
}
}
List<> 已经是 IEnumerable。您不必转换它。
引用 documentation:
public class List<T> : IList<T>, ICollection<T>,
IList, ICollection, IReadOnlyList<T>, IReadOnlyCollection<T>, IEnumerable<T>,
IEnumerable
并且可以通过 List.AddRange()
添加子列表
我能想到至少两个比你现在做的更好的选择:
- 通过将对象传递给递归方法,以递归方式构建单个
List<T>
对象。
- 根本不要构建
List<T>
对象;相反,只是递归地计算迭代器。
#1 的示例(除了原始代码中最明显的 bugs/syntax 错误外,我没有尝试清理任何错误):
private IEnumerable<object> HandleChildItems()
{
var itemsList = new List<Item>();
GetChildItems(xmlnode, itemsList);
// IEnumerable<T> is covariant
return itemsList;
}
private void GetChildItems(XMLnodeList nodeList, List<Item> itemsList)
{
// Here I recursively call the method to add the items to list
foreach (xmlnode xn in nodeList)
{
if (xn.childnodes.count > 0)
{
GetChildItems(xn.childnodes, itemsList);
}
else
{
itemsList.Add(new Item { Code = "123", Itemtext = "xyz" });
}
}
}
#2 示例:
private IEnumerable<object> HandleChildItems()
{
foreach (Item item in GetChildItems(xmlnode))
{
yield return item;
}
}
private IEnumerable<Item> GetChildItems(XMLnodeList nodeList)
{
// Here I recursively call the method to add the items to list
foreach (xmlnode xn in nodeList)
{
if (xn.childnodes.count > 0)
{
foreach (Item item in GetChildItems(xn.childnodes))
{
yield return item;
}
}
else
{
yield return new Item { Code = "123", Itemtext = "xyz" };
}
}
}
示例 #1 的优点是您只创建了一个中间对象,即 List<Item>
本身。但它确实需要将整个列表一次存储在内存中。
示例 #2 创建了一个潜在的大量迭代器方法对象,每个递归级别一个。但是这个数字可能比您必须创建的 Item
个对象的总数小得多,并且您确实避免了必须一次将所有这些 Item
个对象存储在内存中。
我有一个方法 HandleChildItems
,它 return 是一个 IEnumerable<object>
。这个方法又调用了一个方法GetChildItems
。在 GetChildItems
方法中,我进行递归调用以将项目添加到列表中,然后 GetChildItems
方法 return 将列表返回到 HandleChildItems
方法。
return 它作为 IEnumerable
我是 运行 foreach
在 HandleChildItems
方法的项目列表上循环 yield return
.
但这似乎需要更多时间,因为我的 xml 文件有超过 10 万个条目。
有没有办法在调用递归方法本身的同时处理这个问题?
private IEnumerable<object> HandleChildItems()
{
var childItemslst = new List<Item>();
childItemslst = GetChildItems(xmlnode);
foreach (var item in childItemslst)
{
yield return item ;
}
}
private List<Item> GetchildItems(XMLnodeList nodeList)
{
List<Item> lstItem = new List<Item>();
// Here I recursively call the method to add the items to list
foreach (xmlnode xn in nodeList)
{
if (xn.childnodes.count > 0)
{
GetChildItems(xn.childnodes);
}
else
{
item = new Item
{
Code = "123",
Itemtext = "xyz"
};
}
lstItem.add(item);
}
}
List<> 已经是 IEnumerable。您不必转换它。
引用 documentation:
public class List<T> : IList<T>, ICollection<T>,
IList, ICollection, IReadOnlyList<T>, IReadOnlyCollection<T>, IEnumerable<T>,
IEnumerable
并且可以通过 List.AddRange()
添加子列表我能想到至少两个比你现在做的更好的选择:
- 通过将对象传递给递归方法,以递归方式构建单个
List<T>
对象。 - 根本不要构建
List<T>
对象;相反,只是递归地计算迭代器。
#1 的示例(除了原始代码中最明显的 bugs/syntax 错误外,我没有尝试清理任何错误):
private IEnumerable<object> HandleChildItems()
{
var itemsList = new List<Item>();
GetChildItems(xmlnode, itemsList);
// IEnumerable<T> is covariant
return itemsList;
}
private void GetChildItems(XMLnodeList nodeList, List<Item> itemsList)
{
// Here I recursively call the method to add the items to list
foreach (xmlnode xn in nodeList)
{
if (xn.childnodes.count > 0)
{
GetChildItems(xn.childnodes, itemsList);
}
else
{
itemsList.Add(new Item { Code = "123", Itemtext = "xyz" });
}
}
}
#2 示例:
private IEnumerable<object> HandleChildItems()
{
foreach (Item item in GetChildItems(xmlnode))
{
yield return item;
}
}
private IEnumerable<Item> GetChildItems(XMLnodeList nodeList)
{
// Here I recursively call the method to add the items to list
foreach (xmlnode xn in nodeList)
{
if (xn.childnodes.count > 0)
{
foreach (Item item in GetChildItems(xn.childnodes))
{
yield return item;
}
}
else
{
yield return new Item { Code = "123", Itemtext = "xyz" };
}
}
}
示例 #1 的优点是您只创建了一个中间对象,即 List<Item>
本身。但它确实需要将整个列表一次存储在内存中。
示例 #2 创建了一个潜在的大量迭代器方法对象,每个递归级别一个。但是这个数字可能比您必须创建的 Item
个对象的总数小得多,并且您确实避免了必须一次将所有这些 Item
个对象存储在内存中。