很多时候我需要这样的东西:
foreach (Line line in lines)
{
if (line.FullfilsCertainConditions())
{
lines.Remove(line)
}
}
这不起作用,因为我总是得到一个InvalidOperationException
因为枚举器在循环期间发生了变化。
所以我将所有此类循环更改为以下内容:
List<Line> remove = new List<Line>();
foreach (Line line in lines)
{
if (line.FullfilsCertainConditions())
{
remove.Add(line)
}
}
foreach (Line line in remove) {
{
lines.Remove(line);
}
我不确定这是否真的是最好的方法,因为在最坏的情况下我必须在原始列表上迭代 2 次,所以它需要时间 2n 而不是 n。
有一个更好的方法吗?
EDIT:
我可以使用 Mark 的答案来做到这一点!但是如果我的集合没有实现RemoveAll()怎么办?
例如一个
System.Windows.Controls.UIElementCollection
EDIT 2:
再次在 Mark 的帮助下,我现在可以进行以下调用来删除所有 ScatterViewItems:
CollectionUtils.RemoveAll(manager.getWindow().IconDisplay.Items, elem => elem.GetType() == typeof(ScatterViewItem));
这个是直接烤进去的List<T>
:
lines.RemoveAll(line => line.FullfilsCertainConditions());
或者在 C# 2.0 中:
lines.RemoveAll(delegate(Line line) {
return line.FullfilsCertainConditions();
});
在非List<T>
案例(您对问题的编辑),您可以将其包装如下(未经测试):
static class CollectionUtils
{
public static void RemoveAll<T>(IList<T> list, Predicate<T> predicate)
{
int count = list.Count;
while (count-- > 0)
{
if (predicate(list[count])) list.RemoveAt(count);
}
}
public static void RemoveAll(IList list, Predicate<object> predicate)
{
int count = list.Count;
while (count-- > 0)
{
if (predicate(list[count])) list.RemoveAt(count);
}
}
}
Since UIElementCollection
实现(非通用)IList
这应该有效。并且相当方便,使用 C# 3.0,您可以添加this
before IList
/ IList<T>
并将其作为扩展方法。唯一的微妙之处是匿名方法的参数将是object
,所以你需要将其丢弃。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)