从IList中删除匹配谓词的N个项目

时间:2014-02-12 19:32:22

标签: c#

我想从IList集合中删除N个项目。这就是我所拥有的:

public void RemoveSubcomponentsByTemplate(int templateID, int countToRemove)
{
    //  TaskDeviceSubcomponents is an IList
    var subcomponents = TaskDeviceSubcomponents.Where(tds => tds.TemplateID == templateID).ToList();

    if (subcomponents.Count < countToRemove)
    {
        string message = string.Format("Attempted to remove more subcomponents than found. Found: {0}, attempted: {1}", subcomponents.Count, countToRemove);
        throw new ApplicationException(message);
    }

    subcomponents.RemoveRange(0, countToRemove);
}

不幸的是,此代码不像宣传的那样有效。 TaskDeviceSubcomponents是一个IList,因此它没有RemoveRange方法。所以,我调用.ToList()来实例化一个实际的List,但这给了我一个重复的集合,引用了相同的集合项。这不好,因为在子组件上调用RemoveRange不会影响TaskDeviceSubcomponents。

有没有简单的方法来实现这一目标?我只是没有看到它。

1 个答案:

答案 0 :(得分:2)

不幸的是,我认为您需要逐个删除每个项目。我会将您的代码更改为:

public void RemoveSubcomponentsByTemplate(int templateID, int countToRemove)
{
    //  TaskDeviceSubcomponents is an IList
    var subcomponents = TaskDeviceSubcomponents
                         .Where(tds => tds.TemplateID == templateID)
                         .Take(countToRemove)
                         .ToList();

    foreach (var item in subcomponents)
    {
        TaskDeviceSubcomponents.Remove(item);
    }
}

请注意,在此处使用ToList非常重要,因此您在删除部分内容时不会迭代TaskDeviceSubcomponents。这是因为LINQ使用延迟评估,因此在迭代TaskDeviceSubcomponents之前,它不会迭代subcomponents

修改:我忽略了仅删除countToRemove中包含的项目数,因此我在Take之后添加了Where次来电。

编辑2: Take()规范 - 方法:http://msdn.microsoft.com/en-us/library/bb503062(v=vs.110).aspx