前言
在Dotnet開發過程中,DefaultIfEmpty作為IEnumerable的擴展方法,十分常用。本文對DefaultIfEmpty方法的關鍵源碼進行簡要分析,以方便大家日后更好的使用該方法。
使用
DefaultIfEmpty?返回 IEnumerable< T> 的元素;如果序列為空,則返回一個具有默認值的單例類集合。
假如我們有這樣的一個集合,如果集合的元素為空,我們給該集合添加一個默認元素.
public?class?UserInforMation{public?string?UserName?{?get;?set;?}public?string?Sex?{?get;?set;?}}
List<UserInforMation>?lstUserInforMations?=?new?List<UserInforMation>();
不使用Linq 我們可能會這樣寫
private?List<UserInforMation>?DefaultIfEmpty(List<UserInforMation>?userInforMations,?UserInforMation?defaultUser){if?(userInforMations?==?null){throw?new?Exception("數據源為空");}if?(userInforMations.Any()){return?userInforMations;}else{userInforMations.Add(defaultUser);return?userInforMations;}
}
使用Linq
lstUserInforMations.DefaultIfEmpty(new?UserInforMation?{?UserName?=?"張三",?Sex?=?"男"?});
源碼解析
方法
public?static?IEnumerable<TSource>?DefaultIfEmpty<TSource>(IEnumerable<TSource>?source,?TSource?defaultValue)
參數
source 返回的序列。
defaultValue 序列為空時要返回的默認值。
返回值
IEnumerable< TSource> 如果 source 為空,則為包含 defaultValue 的 IEnumerable< T>;否則為 source。
此方法通過使用延遲執行來實現,因為IEnumerable是延遲加載的,每次訪問的時候才取值。所以我們在返回數據時需要使用yield
由于我們需要判斷當前集合是否有元素,所以我們需要使用到GetEnumerator()
源碼
public?static?IEnumerable<TSource>?DefaultIfEmpty<TSource>(IEnumerable<TSource>?source,?TSource?defaultValue){if?(source?==?null){throw?new?Exception("source?is?null");}using?(IEnumerator<TSource>?e?=?source.GetEnumerator()){if?(e.MoveNext()){do{yield?return?e.Current;}while?(e.MoveNext());}else{yield?return?defaultValue;}}}
總結
此方法本人用于處理空集合。該方法顯示默認值,而不是顯示錯誤。
List<UserInforMation>?lstUserInforMations?=?new?List<UserInforMation>();
var?userInfor?=?lstUserInforMations.FirstOrDefault();
if?(userInfor?==?null){userInfor?=?new?UserInforMation?{?UserName?=?"張三",?Sex?=?"男"?};}
使用DefaultIfEmpty可以讓代碼變得更優雅一點
List<UserInforMation>?lstUserInforMations?=?new?List<UserInforMation>();var?userInfor?=?lstUserInforMations.DefaultIfEmpty(new?UserInforMation?{?UserName?=?"張三",?Sex?=?"男"?}).First();
大家要是有更好的使用技巧,歡迎交流,獨樂樂不如眾樂樂,本篇就說到這里啦,希望對您有幫助。