[英]Weird issue about IEnumerable<T> collection
我有以下代码:
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返回一个新集合
但是,仅通过提供的代码难以推断出这种正确性。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.