我有这段简单的代码:
IEnumerable<AccessData> reports = _model.GetAllAccessEvents();
foreach (var ap in AccessPoints.Where(x => !x.IsChecked))
reports = reports.Where(x => x.AccessPointId != ap.Id);
它应该从 reports
IEnumerable 中删除未检查的对象。但它不起作用(它返回完整列表)。除非我这样做:
foreach (var ap in AccessPoints.Where(x => !x.IsChecked))
reports = reports.Where(x => x.AccessPointId != ap.Id).**ToList()**;
然后结果就会被正确过滤。为什么我需要在逻辑中间枚举结果才能使其工作?
最佳答案
您使用的是哪个版本的 C#? C# 5 中闭包中循环变量的行为发生了变化(如果我没记错的话)。如果这确实是您的问题,那么以下方法也应该有效:
IEnumerable<AccessData> reports = _model.GetAllAccessEvents();
foreach (var ap in AccessPoints.Where(x => !x.IsChecked))
{
var closureAp = ap;
reports = reports.Where(x => x.AccessPointId != closureAp.Id);
}
也许更高效,但不太简洁(假设 Id 的类型是 int
;根据需要进行更改):
var reports = _model.GetAllAccessEvents().ToList();
var idsToRemove = new HashSet<int>(AccessPoints.Where(x => !x.IsChecked).Select(x => x.Id));
reports.RemoveAll(report -> idsToRemove.Contains(report.AccessPointId));
或
var reports =
from accessPoint in AccessPoints
where !accessPoint.IsChecked
join accessEvent in _model.GetAllAccessEvents()
on accessPoint.Id equals accessEvent.AccessPointId
select accessEvent;
请注意,使用Join
或HashSet将为算法提供更好的时间复杂度,这意味着随着元素数量的增长,其性能下降的速度会更慢。
关于c# - 为什么我需要在程序逻辑中枚举我的列表才能在这种情况下工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21464417/