关于IEnumerable收集
本文关键字:收集 IEnumerable 关于 | 更新日期: 2023-09-27 18:06:31
我有以下代码:
IEnumerable<TreeItem> rootTreeItems = BuildRootTreeItems();
BuildTreeView(rootTreeItems.ElementAt(0));
private static void BuildTreeView(TreeItem treeItem)
{
TreeItem subMenuTreeItem = new TreeItem();
subMenuTreeItem.Header = "1";
TreeItem subMenuTreeItem2 = new TreeItem();
subMenuTreeItem.Header = "2";
treeItem.TreeItems.Add(subMenuTreeItem);
treeItem.TreeItems.Add(subMenuTreeItem2);
}
奇怪的是在BuildTreeView返回后,rootTreeItems的第一个元素没有任何子节点,而它在调试到BuildTreeView方法时确实有。
这个问题真的困扰了我很长一段时间,有人有什么办法吗?非常感谢。您很可能遇到IEnumerable<>
的延迟执行问题。要记住的是,您的IEnumerable<TreeItem> rootTreeItems
不是一个列表,相反,它是一个承诺,每次被要求这样做时都会获得一个列表。
因此,如果BuildRootTreeItems()
使用LINQ查询创建IEnumerable<TreeItem>
并且它不强制使用.ToList()
或.ToArray()
执行查询,那么每次使用rootTreeItems
时,您都在BuildRootTreeItems()
中重新执行查询
调用rootTreeItems.ElementAt(0)
将导致查询执行。如果稍后您尝试再次调用rootTreeItems.ElementAt(0)
,那么您将重新执行查询并返回第一个TreeItem
的不同实例。
试着像这样改变第一行:
IEnumerable<TreeItem> rootTreeItems = BuildRootTreeItems().ToArray();
强制执行,并防止以后再次执行。
有可能你的BuildRootTreeItems()方法返回IEnumerable接口,这些元素是通过yield语句创建的,或者正如Gabe在上面的评论中提到的,IEnumerable是通过包含Select方法的Linq表达式链创建的。
这可以导致在每次从枚举中访问任何元素时重新创建IEnumerable元素,或者使用Linq表达式或foreach语句通过它进行迭代。
我会写得更简单:
如果
A) TreeItem是值类型(struct)
B) TreeItem。TreeItems返回一个新的集合
但是仅从所提供的代码中很难推断其正确性