因為要取兩個集合不同的元素,所以寫了個拓展方法,用到了yield這個關鍵字,然后就學習了一波。先上代碼
public static IEnumerable<T> NoRetainAll<T>(this IList<T> source, IList<T> compareSource) { foreach (var info in source) { if (!compareSource.Contains(info)) yield return info; } }
yield return與return的區別
返回值類型:
return 可以返回任意類型T;
yield return 只能返回IEnumerable<T>類型,總是個可枚舉的對象,yield return 后面的表達式為T類型。如果沒有元素,也會返回一個count=0的IEnumerable<T>結果,所以不會出現NULL
程序控制流程不同:
return 語句使方法返回,后面再有語句都不執行了。
yield return 則不會使方法返回,繼續執行后面的語句,只是計算記錄最終返回的可枚舉對象的一個元素值
這篇文章介紹的兩者的區別還挺詳細https://www.cnblogs.com/fanyf/p/4565385.html。
上述方法參數為什么要用IList<T>作類型了,因為用IEnumerable<T>,編譯器里面的Reshaper警告提示 Possible multiple enumeration of IEnumerable
這篇文章介紹了原因https://blog.csdn.net/aixun4106/article/details/101972058,還給出了例子,
分析:如果對IEnumerable多次讀取操作,會有因數據源改變導致前后兩次枚舉項不固定的風險,最突出例子是讀取數據庫的時候,第二次foreach時恰好數據源發生了改變,那么讀取出來的數據和第一次就不一致了。
解決方案:多次使用IEnumerable時,最好轉換為List或者Array
個人理解:IEnumerable相當於懶加載,就是數據不是一次性到內存里面的,而List是一次性到內存當中的,所以IEnumerable可能會改變,而List不會改變