LINQ类型转换异常:WhereListIterator无法转为List<UserView>
问题根源与解决方案
错误本质
你遇到的Unable to cast object of type 'WhereListIterator1[UserView]' to type 'System.Collections.Generic.List1[UserView]'错误,核心是类型不匹配:
- LINQ的
Where方法返回的WhereListIterator<T>是IEnumerable<T>的实现类,但它并不是List<T>类型。 - 你的
rowCollection变量被声明为List<UserView>,直接把Where的结果赋值给它时,VB编译阶段的隐式转换可能不会报错,但运行时(尤其是延迟执行触发迭代操作时)会抛出类型转换异常。
代码中的问题点
- 类型赋值矛盾:初始时你通过
ToList()将GetPageduserData的结果转为List<UserView>赋值给rowCollection,但当userIdFilter.Count超过阈值时,直接把Where的延迟执行结果(WhereListIterator<UserView>)赋值给同一个List<UserView>类型变量,本身就存在类型兼容问题。 - 延迟执行导致偶发性:LINQ的
Where是延迟执行逻辑,只有当后续代码迭代结果时才会真正执行查询。这就导致错误不会每次触发——只有走到该分支,且后续代码尝试将rowCollection当作List<UserView>操作(比如调用List专属方法、强制转换)时,才会抛出异常,所以表现为偶发。
修复方案
方案1:统一赋值为List实例
无论什么分支,确保赋值给rowCollection的始终是List<UserView>实例:
当处理userIdFilter超过阈值的分支时,给Where的结果加上ToList():
' 原错误代码 rowCollection = rowCollection.Where(Function(u) userIdFilter.Contains(u.UserId)) ' 修改后 rowCollection = rowCollection.Where(Function(u) userIdFilter.Contains(u.UserId)).ToList()
方案2:调整变量类型为IEnumerable
如果后续代码不需要List<T>特有的方法(比如Add、Remove),可以将rowCollection的声明改为IEnumerable<UserView>,避免强制类型匹配:
Dim rowCollection As IEnumerable(Of UserView) = GetPageduserData().ToList() ' 后续分支直接赋值Where结果即可,按需转换为List rowCollection = rowCollection.Where(Function(u) userIdFilter.Contains(u.UserId))
内容的提问来源于stack exchange,提问作者Hoàng Nguyễn
相关产品推荐
相关产品推荐

