我经常需要这样的东西:
foreach (Line line in lines)
{
if (line.FullfilsCertainConditions())
{
lines.Remove(line)
}
}
Run Code Online (Sandbox Code Playgroud)
这不起作用,因为我总是得到一个InvalidOperationException因为Enumerator在循环期间被更改了.
所以我将所有这种循环改为以下内容:
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);
}
Run Code Online (Sandbox Code Playgroud)
我不确定这是否真的是最好的方法,因为在最坏的情况下我必须在原始列表上迭代2次,因此它需要时间2n而不是n.
有一个更好的方法吗?
编辑:
我能够使用Mark的答案来做到这一点!但是如果我的集合没有实现RemoveAll()怎么办?
例如a
System.Windows.Controls.UIElementCollection
编辑2:
再次在Mark的帮助下,我现在能够进行以下调用以删除所有ScatterViewItems:
CollectionUtils.RemoveAll(manager.getWindow().IconDisplay.Items, elem => elem.GetType() == typeof(ScatterViewItem));
Run Code Online (Sandbox Code Playgroud)
Mar*_*ell 17
这直接烘焙到List<T>:
lines.RemoveAll(line => line.FullfilsCertainConditions());
Run Code Online (Sandbox Code Playgroud)
或者在C#2.0中:
lines.RemoveAll(delegate(Line line) {
return line.FullfilsCertainConditions();
});
Run Code Online (Sandbox Code Playgroud)
在非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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
由于UIElementCollection实现(非泛型)IList这应该工作.而且比较方便,用C#3.0,你可以添加一个this前IList/ IList<T>并将它作为一个扩展方法.唯一的微妙之处在于anon-method的参数将是object,所以你需要将其抛弃.
| 归档时间: |
|
| 查看次数: |
7583 次 |
| 最近记录: |