枚举OrderedEnumerable时排序顺序为何异常?
Linq OrderBy后枚举结果排序异常问题
代码示例
// elements is of type ReadOnlyCollection<IWebElement> var elements = Context.Driver.FindElements(By.XPath(path)); // sortedElements is of type OrderedEnumerable<IWebElement, int> var sortedElements = elements.OrderBy(a => a.Point.Y); // a.Point.Y is an int // 调试时查看sortedElements显示已按Y正确排序 foreach (var row in sortedElements.ToList()) { System.Console.WriteLine(row.Point.Y); // 此处输出的Y值顺序不符合预期,和调试时看到的排序不一致 }
可能的原因
- 元素坐标动态变化:WebElement的
Point属性是实时计算的,调试时查看排序结果的时机,和调用ToList()枚举的时机之间,页面可能发生了布局变化(比如滚动、元素加载完成、DOM重排),导致元素的Y坐标已经改变。 - Linq延迟执行特性:
OrderBy返回的OrderedEnumerable是延迟查询,不会立即执行排序。调试器查看该对象时会触发一次枚举(此时用的是当时的Y值排序),而后续调用ToList()会再次执行一次排序逻辑,此时获取的Y值如果已经变化,结果自然不同。 - DOM元素更新:两次枚举之间页面DOM发生了更新,虽然还是同一个
IWebElement引用,但它对应的实际页面元素位置已经被重新渲染,导致Point.Y值改变。
解决办法
提前缓存元素的Y值,避免多次获取时的不一致:
// 先把元素和对应的Y值缓存到本地列表 var elementsWithFixedY = elements.Select(e => new { Element = e, FixedY = e.Point.Y }).ToList(); // 基于缓存的Y值排序 var sortedElements = elementsWithFixedY.OrderBy(item => item.FixedY); foreach (var row in sortedElements) { Console.WriteLine(row.FixedY); // 需要操作元素时用row.Element }
内容的提问来源于stack exchange,提问作者sy89
相关产品推荐
相关产品推荐

