避免通过列表进行两次迭代

时间:2012-07-11 13:29:26

标签: c# generics linq-to-objects

我有一个通用列表,我使用linq进行搜索:

NotificationWindowItem item = itemList.Where(elm => elm.UID == UID).SingleOrDefault();
itemList.Where(elm => elm.UID == UID).SingleOrDefault().Read = true;

然后我继续使用item的值调用WCF Web服务。 我这样做是因为我理解SingleOrDefault()返回一个新的IEnumerable,带有对象的副本。 (我误解了吗?) 列表通常不会很长,所以额外的迭代不是很重要,但它确实让我感到困扰。

我只是想不出一种巩固两次迭代的方法。 有什么想法吗?

3 个答案:

答案 0 :(得分:4)

SingleOrDefault不会返回IEnumerable而是返回单个项目。既然您已将其分配并保存在变量item中,为什么不直接使用它进行进一步处理?

NotificationWindowItem item = itemList.Where(elm => elm.UID == UID).SingleOrDefault();
item.Read = true;

您可以进一步简化此操作。而且,正如蒂姆所指出的,你需要一个空检查(见下面原因):

NotificationWindowItem item = itemList.SingleOrDefault(elm => elm.UID == UID);
if (item == null)
{
    // ... some alternative or error handling code
}
else
{
    item.Read = true;
}

扩展你的问题/不明智:

  1. itemList是项目列表。每个项目都是NotificationWindowItem。该列表实现了IEnumerable接口。 (更准确地说,我假设itemList是List<NotificationWindowItem>,它实现了IEnumerable<NotificationWindowItem>
  2. 扩展方法在哪里取IEnumerable<NotificationWindowItem>并创建另一个只包含匹配元素的IEnumerable<NotificationWindowItem>
  3. SingleOrDefault采用IEnumerable<NotificationWindowItem>并返回正常的,简单的单个NotificationWindowItem。 (更重要的是,它验证只有一个匹配元素。如果多个元素匹配则会引发异常。如果没有元素匹配,则返回default(T),在您的情况下为null )。
  4. item IEnumerable。这是NotificationWindowItem。背后没有魔法。这是一个简单的对象。它与LINQ没有任何关系。您只使用LINQ来检索它,但之后您可以对NotificationWindowItem的任何其他实例执行任何操作。

答案 1 :(得分:1)

你可以这样做 - 不需要双循环。

var item = itemList.SingleOrDefault(elm => elm.UID == UID);
item.Read = true;

答案 2 :(得分:0)

你可以使用它,

NotificationWindowItem item = itemList.Where(elm => elm.UID == UID).SingleOrDefault().toList(); 

解决您的问题。