myGenericList.RemoveAll(x => (x.StudentName == "bad student"));
效果很好,但绑定列表没有此方法。我如何为绑定列表创建一个扩展方法,该方法将谓词作为输入,并像列表
的固定removeall一样发挥作用三江源
答案 0 :(得分:5)
就像我在评论中所说的那样,扩展方法没有神奇之处,只需像编写正常代码一样编写代码,只需将其放在静态类中的静态方法中并使用{{1}即可。 } keyword:
this
您必须使用public static void RemoveAll<T>(this BindingList<T> list, Func<T, bool> predicate)
{
foreach (var item in list.Where(predicate).ToArray())
list.Remove(item);
}
(或ToArray()
),因为ToList()
是惰性的,只在需要时枚举该集合,您无法枚举更改集合。
虽然这个解决方案很慢(O(N 2 )),因为每个Where()
都必须查看集合才能找到要删除的正确项目。我们可以做得更好:
Remove()
这使用了我们可以在恒定时间内到达第i个项目的事实,因此整个方法是O(N)。迭代更容易向后写,因此我们尚未考虑的项目索引不会改变。
编辑:实际上第二个解决方案仍然是O(N 2 ),因为每个public static void FastRemoveAll<T>(this BindingList<T> list, Func<T, bool> predicate)
{
for (int i = list.Count - 1; i >= 0; i--)
if (predicate(list[i]))
list.RemoveAt(i);
}
必须移动所有项目后移除的项目
答案 1 :(得分:1)
我会说:
public static class BindingListExtensions
{
public static void RemoveAll<T>(this BindingList<T> list, Func<T, bool> predicate)
{
// first check predicates -- uses System.Linq
// could collapse into the foreach, but still must use
// ToList() or ToArray() to avoid deferred execution
var toRemove = list.Where(predicate).ToList();
// then loop and remove after
foreach (var item in toRemove)
{
list.Remove(item);
}
}
}
对于那些对细节感兴趣的人来说,似乎ToList()和ToArray()是如此接近相同的表现(实际上每个都可以根据情况更快),可以忽略不计:I need to iterate and count. What is fastest or preferred: ToArray() or ToList()? < / p>