如何创建一个扩展方法来处理带有谓词输入的bindinglist.removeall

Gul*_*llu 2 c# generics lambda extension-methods predicate

myGenericList.RemoveAll(x => (x.StudentName == "bad student"));
Run Code Online (Sandbox Code Playgroud)

效果很好,但绑定列表没有这种方法.如何为绑定列表创建一个扩展方法,该方法将谓词作为输入,并像List的canned removeall一样进行魔术

谢谢

svi*_*ick 5

就像我在评论中所说的那样,扩展方法没有神奇之处,只需像编写正常的方法一样编写代码,只需将它放在静态类中的静态方法中并使用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);
}
Run Code Online (Sandbox Code Playgroud)

你必须使用ToArray()(或ToList()),因为它Where()是懒惰的,只在需要时枚举集合,你不能枚举更改集合.

虽然这个解决方案很慢(O(N 2)),因为每个人Remove()都必须通过集合来查找要删除的正确项目.我们可以做得更好:

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);
}
Run Code Online (Sandbox Code Playgroud)

这使用了我们可以在恒定时间内到达第i个项目的事实,因此整个方法是O(N).迭代更容易向后写,因此我们尚未考虑的项目索引不会改变.

编辑:实际上第二个解决方案仍然是O(N 2),因为每个RemoveAt()项目必须移动所有项目后删除.