前言
在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();
大家要是有更好的使用技巧,欢迎交流,独乐乐不如众乐乐,本篇就说到这里啦,希望对您有帮助。