【发布时间】:2009-11-30 22:10:24
【问题描述】:
我使用以下语句的目的是从MachineList 集合(IEnumerable 类型)中获取所有具有i 的MachineStatus 的机器对象。 MachineList 集合并不总是包含状态为 i 的机器。
当没有机器有MachineStatus 的i 时,我想返回一个空集合。我对ActiveMachines(首先使用)的调用有效,但InactiveMachines 无效。
public IEnumerable<Machine> ActiveMachines
{
get
{
return Customer.MachineList
.Where(m => m.MachineStatus == "a");
}
}
public IEnumerable<Machine> InactiveMachines
{
get
{
return Customer.MachineList
.Where(m => m.MachineStatus == "i");
}
}
编辑
经过进一步检查,MachineList 的任何枚举似乎都会导致MachineList 的后续枚举抛出异常:Object reference not set to an instance of an object。
因此,调用ActiveMachines 或InactiveMachines 并不重要,因为这是MachineList 集合的问题。这尤其令人不安,因为我可以通过在代码中调用之前在 Watch 中枚举它来中断对MachineList 的调用。在其最低级别MachineList 实现NHibernate.IQuery 作为IEnumerable 返回。是什么导致MachineList 在初始枚举后丢失其内容?
【问题讨论】:
-
不,枚举时没有什么特别的事情发生;看看调试器中有什么“非活动”等会很有趣。我还想知道(例如)
MachineStatus是否是引发异常的外观属性 - 即public string MachineStatus { get {return someInnerField.Status;}}和someInnerField是null。 -
真正的问题是您要多次枚举
IEnumerable。当您使用IEnumerable时,您同意的隐含合同是仅枚举一次!所以真正的答案不是让您的同事更改他的代码以允许多次枚举,而是让您在某个时候执行Customer.MachineList.ToList(),然后只使用结果列表(或者,再次获得一个新的IEnumerable) .您可以进行惰性评估;你可以缓存它,但不要枚举它两次。您也可以公开IQueryable并多次调用它。
标签: c# linq lambda ienumerable