myGenericList.RemoveAll(x => (x.StudentName == "bad student"));
工程很好,但綁定列表沒有此方法。如何創建爲需要輸入一個謂語,確實神奇像列表中的罐裝removeall過的的BindingList的擴展方法如何創建擴展方法來處理bindinglist.removeall與謂詞輸入
三江源
myGenericList.RemoveAll(x => (x.StudentName == "bad student"));
工程很好,但綁定列表沒有此方法。如何創建爲需要輸入一個謂語,確實神奇像列表中的罐裝removeall過的的BindingList的擴展方法如何創建擴展方法來處理bindinglist.removeall與謂詞輸入
三江源
就像我在評論中說,在擴展中沒有魔法ñ方法,只寫代碼的方式,如果你寫的一般,只是把它放在一個靜態方法在靜態類和使用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()
) ,因爲Where()
很懶,只在需要時枚舉集合,並且不能枚舉更改的集合。
儘管此解決方案相當慢(O(N )),因爲每個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);
}
它使用的事實,我們可以得到第i個在固定時間內的項目,所以整個方法是O(N)。迭代更容易反寫,因此我們尚未考慮的項目索引不會改變。
編輯:實際上第二溶液仍然是O(N 2 ),因爲每RemoveAt()
必須移動已刪除的一個之後的所有項目。
真實的,無論他們以相同的數量級執行。我們兩個解決方案中的每一個的linq表達式對於不瞭解正在發生的新手開發人員來說可能更易於維護。 –
我會說:
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()?
擴展方法將執行與手動完成相同的操作。 – svick
該死的。我希望有一些很酷的lambda技巧或什麼的。任何人 ? – Gullu
本身並不是一個lambda技巧,lambdas只會幫助你處理謂詞。至於Linq,您可以使用Linq來幫助選擇,但Linq方法不會真正改變IEnumerable序列。所以你需要一個選擇組合,然後刪除。感謝svick和詹姆斯,感謝 –