如何在linq中处理空列表等空列表?
下面是一些linqpad测试代码。 当它运行时出错是因为“item”的第二个实例具有子项的空列表而不是空列表。
我想以完全相同的方式处理这两种情况(空或空列表),但我想知道是否有一种更简洁的方法,而不仅仅是在列表上进行空检查,并在存在空值时初始化空列表。
换句话说,我可以这样做:
from si in (i.subitems == null ? new List() : i.subitems)
但那有点难看,我想知道我怎么能改进呢?
public class item { public string itemname { get; set; } public List subitems { get; set; } } void Main() { List myItemList = new List() { new item { itemname = "item1", subitems = new List() { new item { itemname = "subitem1" }, new item { itemname = "subitem2" } } }, new item { itemname = "item2" } }; myItemList.Dump(); var res = (from i in myItemList from si in i.subitems select new {i.itemname, subitemname = si.itemname}).ToList(); res.Dump(); }
作为一个奖励问题,这个相同的linq查询可以表示为lambda并以相同的方式处理null吗?
干杯,克里斯
您可以使用null合并运算符
var res = (from i in myItemList from si in i.subitems ?? new List- () select new { i.itemname, subitemname = si.itemname }).ToList();
但我认为你应该过滤掉那些空的
var res = (from i in myItemList where i.subitems != null from si in i.subitems select new { i.itemname, subitemname = si.itemname }).ToList();
至于lambda版本你可以说
var res = myItemList.Where(x => x.subitems != null) .SelectMany( x => x.subitems.Select( y => new { x.itemname, subitemname = y.itemname } ) );
但查询语法版本更易读。
from si in (i.subitems ?? new List- ())
那个怎么样?
您可以添加(邪恶的)扩展方法来为您完成工作
public static IEnumerable EnsureNotEmpty (this IEnumerable enumerable) { if ( enumerable == null ) { return Enumerable.Empty (); } else { return enumerable; } }
另一种方法是不允许子项为空。 您可以创建项构造函数,以便将子项默认为空列表,然后在子项setter中不允许null。
当然,假设您有权修改项目。
正如Hunter Daley指出的那样,空合并运算符就是您正在寻找的