如何在linq中处理空列表等空列表?

Chr*_*son 7 .net c# linq null-coalescing-operator

下面是一些linqpad测试代码.当它运行时出错,因为"item"的第二个实例具有子项目的空列表而不是空列表.

我想以完全相同的方式处理这两种情况(空或空列表),但我想知道是否有一种更简洁的方法,而不仅仅是对列表进行空检查,并在存在空值时初始化空列表.

换句话说,我可以这样做:

from si in (i.subitems == null ? new List<item>() : i.subitems)
Run Code Online (Sandbox Code Playgroud)

但那有点难看,我想知道我怎么能改进呢?

public class item
{
    public string itemname { get; set; }
    public List<item> subitems { get; set; }
}

void Main()
{
    List<item> myItemList = new List<item>() 
    {
        new item 
        {
            itemname = "item1",
            subitems = new List<item>()
            {
                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();
}
Run Code Online (Sandbox Code Playgroud)

作为一个奖金问题,这个相同的linq查询可以表示为lambda并以相同的方式处理null吗?

干杯,克里斯

jas*_*son 14

您可以使用null合并运算符

var res = (from i in myItemList
           from si in i.subitems ?? new List<item>()
           select new { i.itemname, subitemname = si.itemname }).ToList();
Run Code Online (Sandbox Code Playgroud)

但我认为你应该过滤掉那些空的

var res = (from i in myItemList
           where i.subitems != null
           from si in i.subitems
           select new { i.itemname, subitemname = si.itemname }).ToList();
Run Code Online (Sandbox Code Playgroud)

至于lambda版本你可以说

var res = myItemList.Where(x => x.subitems != null)
                    .SelectMany(
                        x => x.subitems.Select(
                            y => new { x.itemname, subitemname = y.itemname }
                        )
                     );
Run Code Online (Sandbox Code Playgroud)

但查询语法版本更易读.


hun*_*ter 11

from si in (i.subitems ?? new List<item>())
Run Code Online (Sandbox Code Playgroud)

那个怎么样?


Jar*_*Par 9

您可以添加(邪恶的)扩展方法来为您完成工作

public static IEnumerable<T> EnsureNotEmpty<T>(this IEnumerable<T> enumerable) {
  if ( enumerable == null ) {
    return Enumerable.Empty<T>();
  } else { 
    return enumerable;
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 该方法应该被称为`EnsureNotNull(...)`.因为`EnsureNotEmpty(...)`听起来像会添加一个故意的项目. - > (4认同)
  • 为什么你说这是邪恶的?我非常喜欢这种方法. (3认同)